From: Eduardo San Martin Morote Date: Wed, 23 Jul 2025 15:25:00 +0000 (+0200) Subject: feat: expose experimental package X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=94e6813694e4f96a04deeb63c34100d92af18a3c;p=thirdparty%2Fvuejs%2Frouter.git feat: expose experimental package --- diff --git a/package.json b/package.json index ecb70d01..f75c8aca 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ }, "onlyBuiltDependencies": [ "chromedriver", + "esbuild", "geckodriver" ] }, diff --git a/packages/router/package.json b/packages/router/package.json index c136b002..40a7e95a 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -27,6 +27,7 @@ "./dist/*": "./dist/*", "./vetur/*": "./vetur/*", "./package.json": "./package.json", + "./experimental": "./dist/experimental/index.mjs", "./auto-routes": { "types": "./vue-router-auto-routes.d.ts", "node": { @@ -79,8 +80,8 @@ "homepage": "https://router.vuejs.org", "files": [ "index.js", - "dist/*.{js,cjs,mjs}", - "dist/vue-router.d.{ts,mts}", + "dist/**/*.{js,cjs,mjs}", + "dist/**/*.d.{ts,mts}", "vue-router-auto.d.ts", "vue-router-auto-routes.d.ts", "vetur/tags.json", diff --git a/packages/router/src/experimental/index.ts b/packages/router/src/experimental/index.ts index 2f16ccb4..30ec7c68 100644 --- a/packages/router/src/experimental/index.ts +++ b/packages/router/src/experimental/index.ts @@ -1,6 +1,27 @@ -export { experimental_createRouter } from './router' +export { experimental_createRouter, normalizeRouteRecord } from './router' export type { + EXPERIMENTAL_Router_Base, EXPERIMENTAL_Router, EXPERIMENTAL_RouteRecordNormalized, + EXPERIMENTAL_RouterOptions_Base, EXPERIMENTAL_RouterOptions, + EXPERIMENTAL_RouteRecordRaw, + EXPERIMENTAL_RouteRecord_Base, + EXPERIMENTAL_RouteRecord_Group, + EXPERIMENTAL_RouteRecordNormalized_Group, + EXPERIMENTAL_RouteRecord_Matchable, + EXPERIMENTAL_RouteRecordNormalized_Matchable, } from './router' + +export { createStaticResolver } from './route-resolver/resolver-static' +export { + MatcherPatternPathDynamic, + MatcherPatternPathStatic, + MatcherPatternPathStar, +} from './route-resolver/matcher-pattern' +export type { + MatcherPattern, + MatcherPatternHash, + MatcherPatternPath, + MatcherPatternQuery, +} from './route-resolver/matcher-pattern' diff --git a/packages/router/src/new-route-resolver/index.ts b/packages/router/src/experimental/route-resolver/index.ts similarity index 100% rename from packages/router/src/new-route-resolver/index.ts rename to packages/router/src/experimental/route-resolver/index.ts diff --git a/packages/router/src/new-route-resolver/matcher-location.ts b/packages/router/src/experimental/route-resolver/matcher-location.ts similarity index 96% rename from packages/router/src/new-route-resolver/matcher-location.ts rename to packages/router/src/experimental/route-resolver/matcher-location.ts index ec1431cf..8d955b7b 100644 --- a/packages/router/src/new-route-resolver/matcher-location.ts +++ b/packages/router/src/experimental/route-resolver/matcher-location.ts @@ -1,4 +1,4 @@ -import type { LocationQueryRaw } from '../query' +import type { LocationQueryRaw } from '../../query' import type { RecordName } from './resolver' // FIXME: rename to ResolverLocation... instead of MatcherLocation... since they are returned by a resolver diff --git a/packages/router/src/new-route-resolver/matcher-pattern.spec.ts b/packages/router/src/experimental/route-resolver/matcher-pattern.spec.ts similarity index 100% rename from packages/router/src/new-route-resolver/matcher-pattern.spec.ts rename to packages/router/src/experimental/route-resolver/matcher-pattern.spec.ts diff --git a/packages/router/src/new-route-resolver/matcher-pattern.ts b/packages/router/src/experimental/route-resolver/matcher-pattern.ts similarity index 100% rename from packages/router/src/new-route-resolver/matcher-pattern.ts rename to packages/router/src/experimental/route-resolver/matcher-pattern.ts diff --git a/packages/router/src/new-route-resolver/matcher-resolve.spec.ts b/packages/router/src/experimental/route-resolver/matcher-resolve.spec.ts similarity index 100% rename from packages/router/src/new-route-resolver/matcher-resolve.spec.ts rename to packages/router/src/experimental/route-resolver/matcher-resolve.spec.ts diff --git a/packages/router/src/new-route-resolver/matchers/errors.ts b/packages/router/src/experimental/route-resolver/matchers/errors.ts similarity index 100% rename from packages/router/src/new-route-resolver/matchers/errors.ts rename to packages/router/src/experimental/route-resolver/matchers/errors.ts diff --git a/packages/router/src/new-route-resolver/matchers/test-utils.ts b/packages/router/src/experimental/route-resolver/matchers/test-utils.ts similarity index 100% rename from packages/router/src/new-route-resolver/matchers/test-utils.ts rename to packages/router/src/experimental/route-resolver/matchers/test-utils.ts diff --git a/packages/router/src/new-route-resolver/resolver-static.spec.ts b/packages/router/src/experimental/route-resolver/resolver-static.spec.ts similarity index 100% rename from packages/router/src/new-route-resolver/resolver-static.spec.ts rename to packages/router/src/experimental/route-resolver/resolver-static.spec.ts diff --git a/packages/router/src/new-route-resolver/resolver-static.ts b/packages/router/src/experimental/route-resolver/resolver-static.ts similarity index 97% rename from packages/router/src/new-route-resolver/resolver-static.ts rename to packages/router/src/experimental/route-resolver/resolver-static.ts index 8c67f669..0150aa90 100644 --- a/packages/router/src/new-route-resolver/resolver-static.ts +++ b/packages/router/src/experimental/route-resolver/resolver-static.ts @@ -1,10 +1,10 @@ -import { normalizeQuery, parseQuery, stringifyQuery } from '../query' +import { normalizeQuery, parseQuery, stringifyQuery } from '../../query' import { LocationNormalized, NEW_stringifyURL, parseURL, resolveRelativePath, -} from '../location' +} from '../../location' import { MatcherLocationAsNamed, MatcherLocationAsPathAbsolute, @@ -53,7 +53,7 @@ export interface EXPERIMENTAL_ResolverRecord_Base { // TODO: here or in router // redirect?: RouteRecordRedirectOption - parent?: EXPERIMENTAL_ResolverRecord // the parent can be matchable or not + parent?: EXPERIMENTAL_ResolverRecord | null // the parent can be matchable or not // TODO: implement aliases // aliasOf?: this } @@ -79,7 +79,7 @@ export type EXPERIMENTAL_ResolverRecord = | (EXPERIMENTAL_ResolverRecord_Matchable & T) | (EXPERIMENTAL_ResolverRecord_Group & T) -export type EXPERIMENTAL_ResolverStaticRecord = +export type EXPERIMENTAL_ResolverStaticRecord = EXPERIMENTAL_ResolverRecord export interface EXPERIMENTAL_ResolverStatic diff --git a/packages/router/src/new-route-resolver/resolver.spec.ts b/packages/router/src/experimental/route-resolver/resolver.spec.ts similarity index 100% rename from packages/router/src/new-route-resolver/resolver.spec.ts rename to packages/router/src/experimental/route-resolver/resolver.spec.ts diff --git a/packages/router/src/new-route-resolver/resolver.test-d.ts b/packages/router/src/experimental/route-resolver/resolver.test-d.ts similarity index 100% rename from packages/router/src/new-route-resolver/resolver.test-d.ts rename to packages/router/src/experimental/route-resolver/resolver.test-d.ts diff --git a/packages/router/src/new-route-resolver/resolver.ts b/packages/router/src/experimental/route-resolver/resolver.ts similarity index 98% rename from packages/router/src/new-route-resolver/resolver.ts rename to packages/router/src/experimental/route-resolver/resolver.ts index fde6f38f..f6fca8e5 100644 --- a/packages/router/src/new-route-resolver/resolver.ts +++ b/packages/router/src/experimental/route-resolver/resolver.ts @@ -3,21 +3,24 @@ import { normalizeQuery, parseQuery, stringifyQuery, -} from '../query' +} from '../../query' import type { MatcherPattern, MatcherPatternHash, MatcherPatternPath, MatcherPatternQuery, } from './matcher-pattern' -import { warn } from '../warning' -import { encodeQueryValue as _encodeQueryValue, encodeParam } from '../encoding' +import { warn } from '../../warning' +import { + encodeQueryValue as _encodeQueryValue, + encodeParam, +} from '../../encoding' import { LocationNormalized, NEW_stringifyURL, parseURL, resolveRelativePath, -} from '../location' +} from '../../location' import type { MatcherLocationAsNamed, MatcherLocationAsPathAbsolute, @@ -25,8 +28,8 @@ import type { MatcherLocationAsRelative, MatcherParamsFormatted, } from './matcher-location' -import { _RouteRecordProps } from '../typed-routes' -import { comparePathParserScore } from '../matcher/pathParserRanker' +import { _RouteRecordProps } from '../../typed-routes' +import { comparePathParserScore } from '../../matcher/pathParserRanker' /** * Allowed types for a matcher name. diff --git a/packages/router/src/experimental/router.ts b/packages/router/src/experimental/router.ts index 60a70d58..2f9cb342 100644 --- a/packages/router/src/experimental/router.ts +++ b/packages/router/src/experimental/router.ts @@ -22,7 +22,6 @@ import { type RouterHistory, } from '../history/common' import type { PathParserOptions } from '../matcher' -import { type NEW_LocationResolved } from '../new-route-resolver/resolver' import { parseQuery as originalParseQuery, stringifyQuery as originalStringifyQuery, @@ -39,6 +38,7 @@ import { } from '../scrollBehavior' import type { _RouteRecordProps, + NavigationGuard, NavigationGuardWithThis, NavigationHookAfter, RouteLocation, @@ -79,9 +79,11 @@ import { routerViewLocationKey, } from '../injectionSymbols' import { + EXPERIMENTAL_ResolverRecord_Base, + EXPERIMENTAL_ResolverRecord_Group, + EXPERIMENTAL_ResolverRecord_Matchable, EXPERIMENTAL_ResolverStatic, - EXPERIMENTAL_ResolverStaticRecord, -} from '../new-route-resolver/resolver-static' +} from './route-resolver/resolver-static' /** * resolve, reject arguments of Promise constructor @@ -177,33 +179,183 @@ export interface EXPERIMENTAL_RouterOptions_Base extends PathParserOptions { // linkInactiveClass?: string } +// TODO: non matchable and parent +/** + * Internal type for common properties among all kind of {@link RouteRecordRaw}. + */ +export interface EXPERIMENTAL_RouteRecord_Base + extends EXPERIMENTAL_ResolverRecord_Base { + // TODO: + /** + * Where to redirect if the route is directly matched. The redirection happens + * before any navigation guard and triggers a new navigation with the new + * target location. + */ + // redirect?: RouteRecordRedirectOption; + + // TODO: + /** + * Aliases for the record. Allows defining extra paths that will behave like a + * copy of the record. Allows having paths shorthands like `/users/:id` and + * `/u/:id`. All `alias` and `path` values must share the same params. + */ + // alias?: string | string[] + + // TODO: + /** + * Before Enter guard specific to this record. Note `beforeEnter` has no + * effect if the record has a `redirect` property. + */ + // beforeEnter?: + // | NavigationGuardWithThis + // | NavigationGuardWithThis[] + + /** + * Arbitrary data attached to the record. + */ + meta?: RouteMeta + + // TODO: + /** + * Array of nested routes. + */ + // children?: RouteRecordRaw[] + + /** + * Components to display when the URL matches this route. Allow using named views. + */ + components?: Record + + /** + * Parent of this component if any + */ + parent?: EXPERIMENTAL_RouteRecordRaw + + // TODO: + /** + * Allow passing down params as props to the component rendered by `router-view`. + */ + // props?: _RouteRecordProps | Record +} + +export interface EXPERIMENTAL_RouteRecord_Matchable + // preserve the values from the type EXPERIMENTAL_ResolverRecord_Matchable + extends Omit, + EXPERIMENTAL_ResolverRecord_Matchable { + components: Record + + parent?: EXPERIMENTAL_RouteRecordNormalized | null + + redirect?: never +} + +export interface EXPERIMENTAL_RouteRecord_Group + extends Omit< + EXPERIMENTAL_RouteRecord_Base, + // preserve the values from the type EXPERIMENTAL_ResolverRecord_Group + 'name' | 'path' | 'query' | 'hash' | 'parent' + >, + EXPERIMENTAL_ResolverRecord_Group { + components?: Record + + parent?: EXPERIMENTAL_RouteRecordNormalized | null + + // TODO: + // redirect?: something +} + +export type EXPERIMENTAL_RouteRecordRaw = + | EXPERIMENTAL_RouteRecord_Matchable + | EXPERIMENTAL_RouteRecord_Group +// | RouteRecordSingleViewWithChildren +// | RouteRecordMultipleViews +// | RouteRecordMultipleViewsWithChildren +// | RouteRecordRedirect + +export interface EXPERIMENTAL_RouteRecordNoramlized_Base { + /** + * Contains the original modules for lazy loaded components. + * + * @internal + */ + mods: Record + + props: Record + + /** + * Registered leave guards + * + * @internal + */ + leaveGuards: Set + + /** + * Registered update guards + * + * @internal + */ + updateGuards: Set + + // FIXME: remove the need for these + instances: Record +} + +export interface EXPERIMENTAL_RouteRecordNormalized_Group + extends EXPERIMENTAL_RouteRecordNoramlized_Base, + EXPERIMENTAL_RouteRecord_Group { + meta: RouteMeta + parent: EXPERIMENTAL_RouteRecordNormalized | null +} + // TODO: is it worth to have 2 types for the undefined values? +export interface EXPERIMENTAL_RouteRecordNormalized_Matchable + extends EXPERIMENTAL_RouteRecordNoramlized_Base, + EXPERIMENTAL_RouteRecord_Matchable { + meta: RouteMeta + + parent: EXPERIMENTAL_RouteRecordNormalized | null + + // TODO: + // redirect?: unknown + + // TODO: + // props: Record + + components: Record +} + export type EXPERIMENTAL_RouteRecordNormalized = - EXPERIMENTAL_ResolverStaticRecord<{ - /** - * Arbitrary data attached to the record. - */ - meta: RouteMeta - - // TODO: - redirect?: unknown - - /** - * Allow passing down params as props to the component rendered by `router-view`. - */ - props: Record - - /** - * {@inheritDoc RouteRecordMultipleViews.components} - */ - components: Record - - /** - * Contains the original modules for lazy loaded components. - * @internal - */ - mods: Record - }> + | EXPERIMENTAL_RouteRecordNormalized_Matchable + | EXPERIMENTAL_RouteRecordNormalized_Group + +export function normalizeRouteRecord( + record: EXPERIMENTAL_RouteRecord_Matchable +): EXPERIMENTAL_RouteRecordNormalized_Matchable { + // we can't define mods if we want to call defineProperty later + const normalizedRecord: Omit< + EXPERIMENTAL_RouteRecordNormalized_Matchable, + 'mods' + > = { + meta: {}, + // must be defined as non enumerable because it contains modules + // mods: {}, + props: {}, + parent: null, + ...record, + // FIXME: to be removed + instances: {}, + leaveGuards: new Set(), + updateGuards: new Set(), + } + // mods contain modules and shouldn't be copied, + // logged or anything. It's just used for internal + // advanced use cases like data loaders + Object.defineProperty(normalizedRecord, 'mods', { + value: {}, + }) + + return normalizedRecord as EXPERIMENTAL_RouteRecordNormalized_Matchable +} // TODO: probably need some generic types // , @@ -218,7 +370,7 @@ export interface EXPERIMENTAL_RouterOptions * * @experimental */ - resolver: EXPERIMENTAL_ResolverStatic + resolver: EXPERIMENTAL_ResolverStatic } /** @@ -394,7 +546,7 @@ export interface EXPERIMENTAL_Router // TRouteRecordRaw, // extends NEW_MatcherRecordRaw, // TRouteRecord extends NEW_MatcherRecord, // > - extends EXPERIMENTAL_Router_Base { + extends EXPERIMENTAL_Router_Base { /** * Original options object passed to create the Router */ @@ -1273,7 +1425,7 @@ export function experimental_createRouter( * @param matched - array of matched records */ function mergeMetaFields( - matched: NEW_LocationResolved['matched'] + matched: EXPERIMENTAL_RouteRecordNormalized[] ): RouteMeta { return assign({} as RouteMeta, ...matched.map(r => r.meta)) } diff --git a/packages/router/src/navigationGuards.ts b/packages/router/src/navigationGuards.ts index e0389cd7..4904788a 100644 --- a/packages/router/src/navigationGuards.ts +++ b/packages/router/src/navigationGuards.ts @@ -289,6 +289,7 @@ export function extractComponentsGuards( } } + // TODO: extract the logic relying on instances into an options-api plugin // skip update and leave guards if the route component is not mounted if (guardType !== 'beforeRouteEnter' && !record.instances[name]) continue