mobx-route 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +45 -14
- package/index.cjs.map +1 -1
- package/index.d.ts +12 -0
- package/index.js +45 -14
- package/index.js.map +1 -1
- package/package.json +4 -4
- package/react.cjs +7 -6
- package/react.cjs.map +1 -1
- package/react.js +7 -6
- package/react.js.map +1 -1
package/index.cjs
CHANGED
|
@@ -70,6 +70,7 @@ class Route {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
config;
|
|
73
74
|
isDestroyed;
|
|
74
75
|
disposer;
|
|
75
76
|
history;
|
|
@@ -152,9 +153,19 @@ class Route {
|
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
154
155
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)
|
|
156
|
+
*
|
|
157
|
+
* Also true in the short gap after history already matches this route but
|
|
158
|
+
* `confirmOpening` has not started yet (e.g. browser Back) — otherwise every
|
|
159
|
+
* route looks closed for one tick and RouteViewGroup unmounts the page.
|
|
155
160
|
*/
|
|
156
161
|
get isOpening() {
|
|
157
|
-
|
|
162
|
+
if (this.status === "opening") {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return this.status === "closed" || this.status === "unknown";
|
|
158
169
|
}
|
|
159
170
|
/**
|
|
160
171
|
* Matched path segment for current URL.
|
|
@@ -408,6 +419,11 @@ class Route {
|
|
|
408
419
|
}
|
|
409
420
|
return;
|
|
410
421
|
}
|
|
422
|
+
if (this.status !== "opening" && this.status !== "open-confirmed") {
|
|
423
|
+
mobx.runInAction(() => {
|
|
424
|
+
this.status = "opening";
|
|
425
|
+
});
|
|
426
|
+
}
|
|
411
427
|
const trx = {
|
|
412
428
|
url: this.parsedPathData.path,
|
|
413
429
|
params: this.parsedPathData.params,
|
|
@@ -440,7 +456,7 @@ class Route {
|
|
|
440
456
|
}
|
|
441
457
|
const createRoute = (path, config) => new Route(path, config);
|
|
442
458
|
const annotations$2 = [
|
|
443
|
-
[mobx.computed, "isOpened", "indexRoute"],
|
|
459
|
+
[mobx.computed, "isOpened", "indexRoute", "canNavigate"],
|
|
444
460
|
[mobx.observable.shallow, "routes"]
|
|
445
461
|
];
|
|
446
462
|
class RouteGroup {
|
|
@@ -449,6 +465,7 @@ class RouteGroup {
|
|
|
449
465
|
this.routes = routes;
|
|
450
466
|
mobx$1.applyObservable(this, annotations$2);
|
|
451
467
|
}
|
|
468
|
+
_indexRoute;
|
|
452
469
|
routes;
|
|
453
470
|
/**
|
|
454
471
|
* Returns true if at least one route in the group is open.
|
|
@@ -471,33 +488,45 @@ class RouteGroup {
|
|
|
471
488
|
(route) => "isIndex" in route && route.isIndex
|
|
472
489
|
);
|
|
473
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* `true` if `open()` has a target to navigate to —
|
|
493
|
+
* either an own index route or a nested `RouteGroup` that itself can navigate.
|
|
494
|
+
*
|
|
495
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)
|
|
496
|
+
*/
|
|
497
|
+
get canNavigate() {
|
|
498
|
+
if (this.indexRoute) return true;
|
|
499
|
+
for (const routeName in this.routes) {
|
|
500
|
+
const route = this.routes[routeName];
|
|
501
|
+
if (route instanceof RouteGroup && route.canNavigate) {
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
474
507
|
/**
|
|
475
508
|
* Main navigation method for the group.
|
|
476
509
|
*
|
|
477
510
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)
|
|
478
511
|
*/
|
|
479
512
|
open(...args) {
|
|
480
|
-
let lastGroupRoute;
|
|
481
513
|
if (this.indexRoute && "open" in this.indexRoute) {
|
|
482
514
|
this.indexRoute.open(...args);
|
|
483
515
|
return;
|
|
484
516
|
}
|
|
485
517
|
for (const routeName in this.routes) {
|
|
486
518
|
const route = this.routes[routeName];
|
|
487
|
-
if (route instanceof RouteGroup) {
|
|
488
|
-
|
|
519
|
+
if (route instanceof RouteGroup && route.canNavigate) {
|
|
520
|
+
route.open(...args);
|
|
521
|
+
return;
|
|
489
522
|
}
|
|
490
523
|
}
|
|
491
|
-
if (
|
|
492
|
-
|
|
524
|
+
if (process.env.NODE_ENV !== "production") {
|
|
525
|
+
console.warn(
|
|
526
|
+
"Warning #1: RouteGroup.open() cannot navigate\nThis group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\nSee docs: https://js2me.github.io/mobx-route/warnings/1"
|
|
527
|
+
);
|
|
493
528
|
} else {
|
|
494
|
-
|
|
495
|
-
console.warn(
|
|
496
|
-
"Warning #1: RouteGroup.open() cannot navigate\nThis group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no nested RouteGroup, so open() does nothing.\nSee docs: https://js2me.github.io/mobx-route/warnings/1"
|
|
497
|
-
);
|
|
498
|
-
} else {
|
|
499
|
-
console.warn("minified warning #1;see mobx-route docs");
|
|
500
|
-
}
|
|
529
|
+
console.warn("minified warning #1;see mobx-route docs");
|
|
501
530
|
}
|
|
502
531
|
}
|
|
503
532
|
}
|
|
@@ -579,6 +608,7 @@ class VirtualRoute {
|
|
|
579
608
|
this.config.afterOpen?.(this.params, this);
|
|
580
609
|
}
|
|
581
610
|
}
|
|
611
|
+
config;
|
|
582
612
|
isDestroyed;
|
|
583
613
|
disposer;
|
|
584
614
|
query;
|
|
@@ -690,6 +720,7 @@ class VirtualRoute {
|
|
|
690
720
|
this.status = "closed";
|
|
691
721
|
this.params = null;
|
|
692
722
|
});
|
|
723
|
+
this.config.afterClose?.();
|
|
693
724
|
return true;
|
|
694
725
|
}
|
|
695
726
|
destroy() {
|
package/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/utils/is-route-entity.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: TParentRoute;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? (null as unknown as TParentRoute);\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {\n fireImmediately: true,\n });\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\n }\n\n protected get isPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n // biome-ignore lint/correctness/noUnusedVariables: this is need to extract unused fields\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? { ...this.query.data, ...rawQuery }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\n });\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isPathMatched) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n let lastGroupRoute: RouteGroup<any> | undefined;\n\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup) {\n lastGroupRoute = route;\n }\n }\n\n if (lastGroupRoute) {\n lastGroupRoute.open(...args);\n } else {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n this.config.afterOpen?.(this.params!, this);\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["createGlobalDynamicConfig","isObservableHistory","createBrowserHistory","createQueryParams","annotations","computed","observable","applyObservable","reaction","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/utils/is-route-entity.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: TParentRoute;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? (null as unknown as TParentRoute);\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {\n fireImmediately: true,\n });\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n *\n * Also true in the short gap after history already matches this route but\n * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every\n * route looks closed for one tick and RouteViewGroup unmounts the page.\n */\n get isOpening() {\n if (this.status === 'opening') {\n return true;\n }\n\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status === 'open-confirmed' ||\n this.status === 'open-rejected'\n ) {\n return false;\n }\n\n return this.status === 'closed' || this.status === 'unknown';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\n }\n\n protected get isPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? { ...this.query.data, ...rawQuery }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\n });\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isPathMatched) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n // Sync before any await — closes the Back gap where isOpened/isOpening\n // were both false until confirmOpening's first runInAction ran.\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute', 'canNavigate'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * `true` if `open()` has a target to navigate to —\n * either an own index route or a nested `RouteGroup` that itself can navigate.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)\n */\n get canNavigate(): boolean {\n if (this.indexRoute) return true;\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n route.open(...args);\n return;\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n this.config.afterOpen?.(this.params!, this);\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n this.config.afterClose?.();\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["createGlobalDynamicConfig","isObservableHistory","createBrowserHistory","createQueryParams","annotations","computed","observable","applyObservable","reaction","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ interface VirtualOpenExtraParams extends Omit<RouteNavigateParams, 'state' | 'me
|
|
|
9
9
|
}
|
|
10
10
|
interface AbstractVirtualRoute<TParams extends AnyObject | EmptyObject = EmptyObject> {
|
|
11
11
|
isOpened: boolean;
|
|
12
|
+
isOpening: boolean;
|
|
12
13
|
params: TParams | null;
|
|
13
14
|
/**
|
|
14
15
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)
|
|
@@ -145,6 +146,13 @@ declare class RouteGroup<TRoutesCollection extends RoutesCollection> implements
|
|
|
145
146
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)
|
|
146
147
|
*/
|
|
147
148
|
get indexRoute(): AnyRouteEntity | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* `true` if `open()` has a target to navigate to —
|
|
151
|
+
* either an own index route or a nested `RouteGroup` that itself can navigate.
|
|
152
|
+
*
|
|
153
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)
|
|
154
|
+
*/
|
|
155
|
+
get canNavigate(): boolean;
|
|
148
156
|
/**
|
|
149
157
|
* Main navigation method for the group.
|
|
150
158
|
*
|
|
@@ -341,6 +349,10 @@ declare class Route<TPath extends string, TInputParams extends InputPathParams<T
|
|
|
341
349
|
protected get parsedPathData(): ParsedPathData<TPath> | null;
|
|
342
350
|
/**
|
|
343
351
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)
|
|
352
|
+
*
|
|
353
|
+
* Also true in the short gap after history already matches this route but
|
|
354
|
+
* `confirmOpening` has not started yet (e.g. browser Back) — otherwise every
|
|
355
|
+
* route looks closed for one tick and RouteViewGroup unmounts the page.
|
|
344
356
|
*/
|
|
345
357
|
get isOpening(): boolean;
|
|
346
358
|
/**
|
package/index.js
CHANGED
|
@@ -69,6 +69,7 @@ class Route {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
config;
|
|
72
73
|
isDestroyed;
|
|
73
74
|
disposer;
|
|
74
75
|
history;
|
|
@@ -151,9 +152,19 @@ class Route {
|
|
|
151
152
|
}
|
|
152
153
|
/**
|
|
153
154
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)
|
|
155
|
+
*
|
|
156
|
+
* Also true in the short gap after history already matches this route but
|
|
157
|
+
* `confirmOpening` has not started yet (e.g. browser Back) — otherwise every
|
|
158
|
+
* route looks closed for one tick and RouteViewGroup unmounts the page.
|
|
154
159
|
*/
|
|
155
160
|
get isOpening() {
|
|
156
|
-
|
|
161
|
+
if (this.status === "opening") {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
return this.status === "closed" || this.status === "unknown";
|
|
157
168
|
}
|
|
158
169
|
/**
|
|
159
170
|
* Matched path segment for current URL.
|
|
@@ -407,6 +418,11 @@ class Route {
|
|
|
407
418
|
}
|
|
408
419
|
return;
|
|
409
420
|
}
|
|
421
|
+
if (this.status !== "opening" && this.status !== "open-confirmed") {
|
|
422
|
+
runInAction(() => {
|
|
423
|
+
this.status = "opening";
|
|
424
|
+
});
|
|
425
|
+
}
|
|
410
426
|
const trx = {
|
|
411
427
|
url: this.parsedPathData.path,
|
|
412
428
|
params: this.parsedPathData.params,
|
|
@@ -439,7 +455,7 @@ class Route {
|
|
|
439
455
|
}
|
|
440
456
|
const createRoute = (path, config) => new Route(path, config);
|
|
441
457
|
const annotations$2 = [
|
|
442
|
-
[computed, "isOpened", "indexRoute"],
|
|
458
|
+
[computed, "isOpened", "indexRoute", "canNavigate"],
|
|
443
459
|
[observable.shallow, "routes"]
|
|
444
460
|
];
|
|
445
461
|
class RouteGroup {
|
|
@@ -448,6 +464,7 @@ class RouteGroup {
|
|
|
448
464
|
this.routes = routes;
|
|
449
465
|
applyObservable(this, annotations$2);
|
|
450
466
|
}
|
|
467
|
+
_indexRoute;
|
|
451
468
|
routes;
|
|
452
469
|
/**
|
|
453
470
|
* Returns true if at least one route in the group is open.
|
|
@@ -470,33 +487,45 @@ class RouteGroup {
|
|
|
470
487
|
(route) => "isIndex" in route && route.isIndex
|
|
471
488
|
);
|
|
472
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* `true` if `open()` has a target to navigate to —
|
|
492
|
+
* either an own index route or a nested `RouteGroup` that itself can navigate.
|
|
493
|
+
*
|
|
494
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)
|
|
495
|
+
*/
|
|
496
|
+
get canNavigate() {
|
|
497
|
+
if (this.indexRoute) return true;
|
|
498
|
+
for (const routeName in this.routes) {
|
|
499
|
+
const route = this.routes[routeName];
|
|
500
|
+
if (route instanceof RouteGroup && route.canNavigate) {
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
473
506
|
/**
|
|
474
507
|
* Main navigation method for the group.
|
|
475
508
|
*
|
|
476
509
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)
|
|
477
510
|
*/
|
|
478
511
|
open(...args) {
|
|
479
|
-
let lastGroupRoute;
|
|
480
512
|
if (this.indexRoute && "open" in this.indexRoute) {
|
|
481
513
|
this.indexRoute.open(...args);
|
|
482
514
|
return;
|
|
483
515
|
}
|
|
484
516
|
for (const routeName in this.routes) {
|
|
485
517
|
const route = this.routes[routeName];
|
|
486
|
-
if (route instanceof RouteGroup) {
|
|
487
|
-
|
|
518
|
+
if (route instanceof RouteGroup && route.canNavigate) {
|
|
519
|
+
route.open(...args);
|
|
520
|
+
return;
|
|
488
521
|
}
|
|
489
522
|
}
|
|
490
|
-
if (
|
|
491
|
-
|
|
523
|
+
if (process.env.NODE_ENV !== "production") {
|
|
524
|
+
console.warn(
|
|
525
|
+
"Warning #1: RouteGroup.open() cannot navigate\nThis group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\nSee docs: https://js2me.github.io/mobx-route/warnings/1"
|
|
526
|
+
);
|
|
492
527
|
} else {
|
|
493
|
-
|
|
494
|
-
console.warn(
|
|
495
|
-
"Warning #1: RouteGroup.open() cannot navigate\nThis group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no nested RouteGroup, so open() does nothing.\nSee docs: https://js2me.github.io/mobx-route/warnings/1"
|
|
496
|
-
);
|
|
497
|
-
} else {
|
|
498
|
-
console.warn("minified warning #1;see mobx-route docs");
|
|
499
|
-
}
|
|
528
|
+
console.warn("minified warning #1;see mobx-route docs");
|
|
500
529
|
}
|
|
501
530
|
}
|
|
502
531
|
}
|
|
@@ -578,6 +607,7 @@ class VirtualRoute {
|
|
|
578
607
|
this.config.afterOpen?.(this.params, this);
|
|
579
608
|
}
|
|
580
609
|
}
|
|
610
|
+
config;
|
|
581
611
|
isDestroyed;
|
|
582
612
|
disposer;
|
|
583
613
|
query;
|
|
@@ -689,6 +719,7 @@ class VirtualRoute {
|
|
|
689
719
|
this.status = "closed";
|
|
690
720
|
this.params = null;
|
|
691
721
|
});
|
|
722
|
+
this.config.afterClose?.();
|
|
692
723
|
return true;
|
|
693
724
|
}
|
|
694
725
|
destroy() {
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/utils/is-route-entity.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: TParentRoute;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? (null as unknown as TParentRoute);\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {\n fireImmediately: true,\n });\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\n }\n\n protected get isPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n // biome-ignore lint/correctness/noUnusedVariables: this is need to extract unused fields\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? { ...this.query.data, ...rawQuery }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\n });\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isPathMatched) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n let lastGroupRoute: RouteGroup<any> | undefined;\n\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup) {\n lastGroupRoute = route;\n }\n }\n\n if (lastGroupRoute) {\n lastGroupRoute.open(...args);\n } else {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n this.config.afterOpen?.(this.params!, this);\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["annotations"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/utils/is-route-entity.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: TParentRoute;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? (null as unknown as TParentRoute);\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {\n fireImmediately: true,\n });\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n *\n * Also true in the short gap after history already matches this route but\n * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every\n * route looks closed for one tick and RouteViewGroup unmounts the page.\n */\n get isOpening() {\n if (this.status === 'opening') {\n return true;\n }\n\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status === 'open-confirmed' ||\n this.status === 'open-rejected'\n ) {\n return false;\n }\n\n return this.status === 'closed' || this.status === 'unknown';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\n }\n\n protected get isPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? { ...this.query.data, ...rawQuery }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\n });\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isPathMatched) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n // Sync before any await — closes the Back gap where isOpened/isOpening\n // were both false until confirmOpening's first runInAction ran.\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute', 'canNavigate'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * `true` if `open()` has a target to navigate to —\n * either an own index route or a nested `RouteGroup` that itself can navigate.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)\n */\n get canNavigate(): boolean {\n if (this.indexRoute) return true;\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n route.open(...args);\n return;\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n this.config.afterOpen?.(this.params!, this);\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n this.config.afterClose?.();\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["annotations"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobx-route",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"mobx",
|
|
6
6
|
"react",
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"homepage": "https://js2me.github.io/mobx-route",
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "
|
|
22
|
+
"url": "https://github.com/js2me/mobx-route"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"mobx-location-history": "^9.4.
|
|
25
|
+
"mobx-location-history": "^9.4.1",
|
|
26
26
|
"path-to-regexp": "^8.4.2",
|
|
27
|
-
"yummies": "^7.
|
|
27
|
+
"yummies": "^7.20.1"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"mobx": "^6.12.4",
|
package/react.cjs
CHANGED
|
@@ -88,7 +88,8 @@ function RouteViewBase(props) {
|
|
|
88
88
|
if (!("route" in props)) {
|
|
89
89
|
return typeof props.children === "function" ? props.children() : props.children;
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
const isOpening = "isOpening" in props.route && Boolean(props.route.isOpening);
|
|
92
|
+
if (!props.route.isOpened && !isOpening) {
|
|
92
93
|
return props.fallback ?? null;
|
|
93
94
|
}
|
|
94
95
|
Component = props.view;
|
|
@@ -121,15 +122,15 @@ const RouteViewGroup = mobxReactLite.observer(
|
|
|
121
122
|
mobxRoute.isRouteEntity(childNode.props?.route);
|
|
122
123
|
if (isRouteChild) {
|
|
123
124
|
const route = childNode.props.route;
|
|
124
|
-
if (route.isOpened) {
|
|
125
|
+
if (route.isOpened || route.isOpening) {
|
|
125
126
|
activeChildRouteNode = childNode;
|
|
126
|
-
if (!useLastOpened) {
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
127
|
if (route.isOpening) {
|
|
131
128
|
hasRoutesInOpening = true;
|
|
132
129
|
}
|
|
130
|
+
if (!useLastOpened && route.isOpened) {
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
133
134
|
lastInactiveChildNode = childNode;
|
|
134
135
|
}
|
|
135
136
|
} else {
|
package/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.cjs","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n if (!props.route.isOpened) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n if (route.isOpened) {\n activeChildRouteNode = childNode;\n if (!useLastOpened) {\n break;\n }\n } else {\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["observer","forwardRef","useRef","isShallowEqual","useMemo","navigateParams","routeConfig","href","parseSearchString","query","buildSearchString","isValidElement","cloneElement","jsx","isRouteEntity","useEffect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.cjs","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n const isOpening =\n 'isOpening' in props.route &&\n Boolean((props.route as { isOpening?: boolean }).isOpening);\n\n if (!props.route.isOpened && !isOpening) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n // Keep the matched/opening route selected during confirmOpening and the\n // pre-reaction Back gap (isOpening covers path-matched + not confirmed).\n if (route.isOpened || route.isOpening) {\n activeChildRouteNode = childNode;\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n if (!useLastOpened && route.isOpened) {\n break;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["observer","forwardRef","useRef","isShallowEqual","useMemo","navigateParams","routeConfig","href","parseSearchString","query","buildSearchString","isValidElement","cloneElement","jsx","isRouteEntity","useEffect"],"mappings":"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"}
|
package/react.js
CHANGED
|
@@ -86,7 +86,8 @@ function RouteViewBase(props) {
|
|
|
86
86
|
if (!("route" in props)) {
|
|
87
87
|
return typeof props.children === "function" ? props.children() : props.children;
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
const isOpening = "isOpening" in props.route && Boolean(props.route.isOpening);
|
|
90
|
+
if (!props.route.isOpened && !isOpening) {
|
|
90
91
|
return props.fallback ?? null;
|
|
91
92
|
}
|
|
92
93
|
Component = props.view;
|
|
@@ -119,15 +120,15 @@ const RouteViewGroup = observer(
|
|
|
119
120
|
isRouteEntity(childNode.props?.route);
|
|
120
121
|
if (isRouteChild) {
|
|
121
122
|
const route = childNode.props.route;
|
|
122
|
-
if (route.isOpened) {
|
|
123
|
+
if (route.isOpened || route.isOpening) {
|
|
123
124
|
activeChildRouteNode = childNode;
|
|
124
|
-
if (!useLastOpened) {
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
} else {
|
|
128
125
|
if (route.isOpening) {
|
|
129
126
|
hasRoutesInOpening = true;
|
|
130
127
|
}
|
|
128
|
+
if (!useLastOpened && route.isOpened) {
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
131
132
|
lastInactiveChildNode = childNode;
|
|
132
133
|
}
|
|
133
134
|
} else {
|
package/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n if (!props.route.isOpened) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n if (route.isOpened) {\n activeChildRouteNode = childNode;\n if (!useLastOpened) {\n break;\n }\n } else {\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["navigateParams","href","query"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.js","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n const isOpening =\n 'isOpening' in props.route &&\n Boolean((props.route as { isOpening?: boolean }).isOpening);\n\n if (!props.route.isOpened && !isOpening) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n // Keep the matched/opening route selected during confirmOpening and the\n // pre-reaction Back gap (isOpening covers path-matched + not confirmed).\n if (route.isOpened || route.isOpening) {\n activeChildRouteNode = childNode;\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n if (!useLastOpened && route.isOpened) {\n break;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["navigateParams","href","query"],"mappings":"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"}
|