@bleedingdev/modern-js-plugin-tanstack 3.9.0-ultramodern.9 → 3.9.3-ultramodern.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/dist/cjs/cli/artifacts.js +15 -1
- package/dist/cjs/cli/index.js +13 -2
- package/dist/cjs/cli/routeMetadata.js +131 -0
- package/dist/cjs/cli/rscRouteLayer.js +86 -0
- package/dist/cjs/cli/tanstackTypes/canonicalRoutes.js +7 -7
- package/dist/cjs/cli/tanstackTypes/shared.js +0 -14
- package/dist/cjs/cli/tanstackTypes/source.js +28 -63
- package/dist/cjs/runtime/lifecycle.js +0 -3
- package/dist/cjs/runtime/loaderBridge.js +10 -4
- package/dist/cjs/runtime/navigation.js +102 -0
- package/dist/cjs/runtime/plugin.js +10 -1
- package/dist/cjs/runtime/plugin.node.js +89 -64
- package/dist/cjs/runtime/routeTree/construction.js +19 -61
- package/dist/cjs/runtime/routeTree/loaders.js +1 -1
- package/dist/cjs/runtime/routeTree/paths.js +0 -6
- package/dist/cjs/runtime/ssrManagedTags.js +2 -12
- package/dist/cjs/runtime/utils.js +1 -0
- package/dist/cjs/shared/routeDescriptor.js +60 -0
- package/dist/esm/cli/artifacts.mjs +13 -2
- package/dist/esm/cli/index.mjs +13 -11
- package/dist/esm/cli/routeMetadata.mjs +71 -0
- package/dist/esm/cli/rscRouteLayer.mjs +35 -0
- package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +7 -7
- package/dist/esm/cli/tanstackTypes/shared.mjs +1 -9
- package/dist/esm/cli/tanstackTypes/source.mjs +29 -64
- package/dist/esm/runtime/lifecycle.mjs +1 -1
- package/dist/esm/runtime/loaderBridge.mjs +8 -5
- package/dist/esm/runtime/navigation.mjs +64 -0
- package/dist/esm/runtime/plugin.mjs +10 -1
- package/dist/esm/runtime/plugin.node.mjs +91 -66
- package/dist/esm/runtime/routeTree/construction.mjs +19 -61
- package/dist/esm/runtime/routeTree/loaders.mjs +2 -2
- package/dist/esm/runtime/routeTree/paths.mjs +1 -4
- package/dist/esm/runtime/ssrManagedTags.mjs +1 -8
- package/dist/esm/runtime/utils.mjs +1 -0
- package/dist/esm/shared/routeDescriptor.mjs +22 -0
- package/dist/esm-node/cli/artifacts.mjs +13 -2
- package/dist/esm-node/cli/index.mjs +13 -11
- package/dist/esm-node/cli/routeMetadata.mjs +72 -0
- package/dist/esm-node/cli/rscRouteLayer.mjs +36 -0
- package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +7 -7
- package/dist/esm-node/cli/tanstackTypes/shared.mjs +1 -9
- package/dist/esm-node/cli/tanstackTypes/source.mjs +29 -64
- package/dist/esm-node/runtime/lifecycle.mjs +1 -1
- package/dist/esm-node/runtime/loaderBridge.mjs +8 -5
- package/dist/esm-node/runtime/navigation.mjs +65 -0
- package/dist/esm-node/runtime/plugin.mjs +10 -1
- package/dist/esm-node/runtime/plugin.node.mjs +91 -66
- package/dist/esm-node/runtime/routeTree/construction.mjs +19 -61
- package/dist/esm-node/runtime/routeTree/loaders.mjs +2 -2
- package/dist/esm-node/runtime/routeTree/paths.mjs +1 -4
- package/dist/esm-node/runtime/ssrManagedTags.mjs +1 -8
- package/dist/esm-node/runtime/utils.mjs +1 -0
- package/dist/esm-node/shared/routeDescriptor.mjs +23 -0
- package/dist/types/cli/artifacts.d.ts +16 -7
- package/dist/types/cli/index.d.ts +1 -1
- package/dist/types/cli/routeMetadata.d.ts +18 -0
- package/dist/types/cli/rscRouteLayer.d.ts +11 -0
- package/dist/types/cli/tanstackTypes/shared.d.ts +0 -2
- package/dist/types/cli/tanstackTypes/source.d.ts +3 -2
- package/dist/types/runtime/lifecycle.d.ts +1 -1
- package/dist/types/runtime/loaderBridge.d.ts +1 -0
- package/dist/types/runtime/navigation.d.ts +4 -0
- package/dist/types/runtime/pluginShared.d.ts +5 -0
- package/dist/types/runtime/routeTree/paths.d.ts +0 -2
- package/dist/types/runtime/ssrManagedTags.d.ts +0 -1
- package/dist/types/runtime/ssrTypes.d.ts +0 -7
- package/dist/types/shared/routeDescriptor.d.ts +26 -0
- package/package.json +32 -26
- package/src/cli/artifacts.ts +59 -8
- package/src/cli/index.ts +17 -4
- package/src/cli/routeMetadata.ts +121 -0
- package/src/cli/rscRouteLayer.ts +93 -0
- package/src/cli/tanstackTypes/canonicalRoutes.ts +17 -12
- package/src/cli/tanstackTypes/shared.ts +0 -14
- package/src/cli/tanstackTypes/source.ts +48 -120
- package/src/runtime/lifecycle.ts +0 -1
- package/src/runtime/loaderBridge.ts +9 -9
- package/src/runtime/navigation.ts +78 -0
- package/src/runtime/plugin.node.tsx +121 -91
- package/src/runtime/plugin.tsx +10 -0
- package/src/runtime/pluginShared.ts +12 -0
- package/src/runtime/routeTree/construction.ts +32 -112
- package/src/runtime/routeTree/loaders.ts +2 -4
- package/src/runtime/routeTree/paths.ts +0 -6
- package/src/runtime/ssrManagedTags.ts +0 -17
- package/src/runtime/ssrTypes.ts +0 -7
- package/src/runtime/utils.tsx +1 -0
- package/src/shared/routeDescriptor.ts +46 -0
- package/dist/esm/rslib-runtime~1.mjs +0 -18
- package/dist/esm-node/rslib-runtime~0.mjs +0 -19
- package/rslib.config.mts +0 -4
- package/rstest.config.mts +0 -53
- package/tests/router/cli.test.ts +0 -420
- package/tests/router/clientHydration.test.tsx +0 -200
- package/tests/router/dataMutation.test.tsx +0 -428
- package/tests/router/fixtures/router-gen.oxlint.json +0 -5
- package/tests/router/flightSerialization.roundtrip.test.tsx +0 -140
- package/tests/router/generateRouteArtifacts.test.ts +0 -146
- package/tests/router/loaderBridge.test.ts +0 -207
- package/tests/router/localisedIdentity.test.tsx +0 -95
- package/tests/router/prefetchLink.test.tsx +0 -122
- package/tests/router/prefetchLinkPreload.test.tsx +0 -65
- package/tests/router/routeHooks.test.ts +0 -49
- package/tests/router/routeTree.test.ts +0 -240
- package/tests/router/rsc.test.tsx +0 -480
- package/tests/router/serverPlugin.test.ts +0 -157
- package/tests/router/slotUsageSanitizer.test.ts +0 -23
- package/tests/router/ssrPreload.test.ts +0 -30
- package/tests/router/tanstackTypes.test.ts +0 -384
- package/tsconfig.json +0 -12
- package/tsconfig.tsgo.json +0 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import { getLoaderHref, handleModernLoaderError, handleModernLoaderResult, mapSplatParamsForModernLoader } from "../loaderBridge.mjs";
|
|
2
|
+
import { getLoaderHref, getLoaderSignal, handleModernLoaderError, handleModernLoaderResult, mapSplatParamsForModernLoader } from "../loaderBridge.mjs";
|
|
3
3
|
import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "../rsc/payloadRouter.mjs";
|
|
4
4
|
function isModernDeferredData(value) {
|
|
5
5
|
if (!value || 'object' != typeof value) return false;
|
|
@@ -50,7 +50,7 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
|
|
|
50
50
|
if ('function' == typeof modernRoute.lazyImport) try {
|
|
51
51
|
await modernRoute.lazyImport();
|
|
52
52
|
} catch {}
|
|
53
|
-
const signal = ctx
|
|
53
|
+
const signal = getLoaderSignal(ctx);
|
|
54
54
|
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
55
55
|
const href = getLoaderHref(ctx);
|
|
56
56
|
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
async function waitForRouterSerialization(tanstackRouter) {
|
|
3
|
-
const serverSsr = tanstackRouter.serverSsr;
|
|
4
|
-
if (!serverSsr || 'function' != typeof serverSsr.onSerializationFinished || serverSsr.isSerializationFinished?.()) return;
|
|
5
|
-
await new Promise((resolve)=>{
|
|
6
|
-
serverSsr.onSerializationFinished?.(resolve);
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
2
|
function htmlEscapeAttr(value) {
|
|
10
3
|
return value.replace(/&/g, '&').replace(/"/g, '"');
|
|
11
4
|
}
|
|
@@ -51,4 +44,4 @@ async function attachServerSsrUtils(router) {
|
|
|
51
44
|
manifest: void 0
|
|
52
45
|
});
|
|
53
46
|
}
|
|
54
|
-
export { attachServerSsrUtils, collectRouterErrors, createGetSsrHref, routerManagedTagsToHtml
|
|
47
|
+
export { attachServerSsrUtils, collectRouterErrors, createGetSsrHref, routerManagedTagsToHtml };
|
|
@@ -15,6 +15,7 @@ function withGlobalLayout(Component, globalApp) {
|
|
|
15
15
|
function toTanstackRouteObject(route, globalApp) {
|
|
16
16
|
if ('nested' === route.type) return {
|
|
17
17
|
modernLocalisedRoute: Reflect.get(route, 'modernLocalisedRoute'),
|
|
18
|
+
isRoot: Reflect.get(route, 'isRoot'),
|
|
18
19
|
path: route.path,
|
|
19
20
|
id: route.id,
|
|
20
21
|
loader: route.loader,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { toTanstackPath } from "../runtime/routeTree/paths.mjs";
|
|
3
|
+
function describeRouteTree(routes) {
|
|
4
|
+
const root = routes.find((route)=>true === route.isRoot || '/' === route.path && true !== route.index);
|
|
5
|
+
const describe = (route, index)=>({
|
|
6
|
+
source: route,
|
|
7
|
+
location: 0 === (route.path ?? '').length && true !== route.index ? {
|
|
8
|
+
id: route.id || route.file || `pathless-${index}`
|
|
9
|
+
} : {
|
|
10
|
+
path: true === route.index ? '/' : toTanstackPath(route.path || '')
|
|
11
|
+
},
|
|
12
|
+
hasSplat: Boolean(route.path?.includes('*')),
|
|
13
|
+
children: (route.children ?? []).map(describe)
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
root,
|
|
17
|
+
children: (void 0 !== root ? [
|
|
18
|
+
...root.children ?? [],
|
|
19
|
+
...routes.filter((route)=>route !== root)
|
|
20
|
+
] : routes).map(describe)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export { describeRouteTree };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AppTools } from '@modern-js/app-tools/cli-config';
|
|
2
|
+
import type { CLIPluginAPI } from '@modern-js/plugin';
|
|
2
3
|
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
3
4
|
export declare function writeTanstackRegisterFile(opts: {
|
|
4
5
|
entries: string[];
|
|
@@ -9,7 +10,7 @@ export declare function writeTanstackRegisterFile(opts: {
|
|
|
9
10
|
i18nRuntimeModule?: string;
|
|
10
11
|
}): Promise<void>;
|
|
11
12
|
export declare function writeTanstackRouterTypesForEntries(opts: {
|
|
12
|
-
appContext:
|
|
13
|
+
appContext: Pick<ReturnType<CLIPluginAPI<AppTools>['getAppContext']>, 'srcDirectory' | 'internalSrcAlias' | 'entrypoints'>;
|
|
13
14
|
generatedDirName?: string;
|
|
14
15
|
routesByEntry: Record<string, (NestedRouteForCli | PageRoute)[]>;
|
|
15
16
|
/**
|
|
@@ -21,11 +22,19 @@ export declare function writeTanstackRouterTypesForEntries(opts: {
|
|
|
21
22
|
i18nPluginInstalled?: boolean;
|
|
22
23
|
}): Promise<void>;
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
* Writes `src/routes/ultramodern-route-metadata.ts` from the `route.meta.ts`
|
|
26
|
+
* files below `src/routes`. Reads only the file system, never the app config.
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeRouteMetadataManifest(opts: {
|
|
29
|
+
appDirectory: string;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Headless regeneration of the route metadata manifest and of `router.gen.ts` /
|
|
33
|
+
* `register.gen.d.ts` for a generated app, without running a full dev/build.
|
|
34
|
+
* Drives the app-tools analyze `onPrepare` (which fires `generateEntryCode`)
|
|
35
|
+
* and returns before any bundling — the app's own registered plugin-tanstack
|
|
36
|
+
* writes the router artifacts via its `generateEntryCode` subscriber. Reuses
|
|
37
|
+
* the exact hook dev/build use, so there is no scanning drift.
|
|
29
38
|
*/
|
|
30
39
|
export declare function generateTanstackRouteArtifacts(opts: {
|
|
31
40
|
appDirectory: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
2
2
|
import { type TanstackRouteCodeSplittingOption } from './routeSplitting.js';
|
|
3
|
-
export { generateTanstackRouteArtifacts, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries, } from './artifacts.js';
|
|
3
|
+
export { generateTanstackRouteArtifacts, writeRouteMetadataManifest, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries, } from './artifacts.js';
|
|
4
4
|
export type { TanstackRouteCodeSplittingOption, TanstackRsbuildRouteSplittingProfile, } from './routeSplitting.js';
|
|
5
5
|
export { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled, } from './routeSplitting.js';
|
|
6
6
|
export { type CollectCanonicalRoutesOptions, collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry, } from './tanstackTypes.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const ROUTE_META_FILE_NAME = "route.meta.ts";
|
|
2
|
+
export declare const ROUTE_METADATA_MANIFEST_FILE_NAME = "ultramodern-route-metadata.ts";
|
|
3
|
+
export declare const ROUTE_METADATA_MANIFEST_HEADER = "// @generated by @modern-js/plugin-tanstack from route.meta.ts files. Run routes-generate; do not edit.";
|
|
4
|
+
/**
|
|
5
|
+
* Renders the route metadata manifest for the `route.meta.ts` files of one
|
|
6
|
+
* routes directory. Each path is relative to that directory (either separator).
|
|
7
|
+
* Every `route.meta.ts` must export `routeMeta`; the manifest imports it
|
|
8
|
+
* statically, so the metadata is never evaluated while generating. Returns
|
|
9
|
+
* `null` when there are no route metadata files. Output depends only on the
|
|
10
|
+
* set of paths, never on their order or on the file system.
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderRouteMetadataManifest(routeMetaFiles: readonly string[]): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Lists the `route.meta.ts` files below `routesDirectory`, relative to it.
|
|
15
|
+
* Symbolic links are not followed: linked metadata belongs to the tree it
|
|
16
|
+
* lives in. A missing directory has no route metadata.
|
|
17
|
+
*/
|
|
18
|
+
export declare function findRouteMetaFiles(routesDirectory: string): Promise<string[]>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AppNormalizedConfig } from '@modern-js/app-tools/cli-config';
|
|
2
|
+
type BuilderPlugin = NonNullable<AppNormalizedConfig['builderPlugins']>[number];
|
|
3
|
+
export declare const TANSTACK_SERVER_ROUTES_FILE = "tanstack-routes.server.js";
|
|
4
|
+
type RouteLayerContext = {
|
|
5
|
+
entryNames: readonly string[];
|
|
6
|
+
internalDirectory: string;
|
|
7
|
+
rsc: AppNormalizedConfig['server']['rsc'];
|
|
8
|
+
};
|
|
9
|
+
/** The HTML router consumes executable components, while route data stays in Flight. */
|
|
10
|
+
export declare function createTanstackRscRouteLayerPlugin(getContext: () => RouteLayerContext): BuilderPlugin;
|
|
11
|
+
export {};
|
|
@@ -11,8 +11,6 @@ export declare function pickRouteSearchContractModules(route: NestedRouteForCli
|
|
|
11
11
|
validateSearchPath: string | null;
|
|
12
12
|
loaderDepsPath: string | null;
|
|
13
13
|
};
|
|
14
|
-
export declare function isPathlessLayout(route: NestedRouteForCli | PageRoute): boolean;
|
|
15
|
-
export declare function isIndexRoute(route: NestedRouteForCli | PageRoute): boolean;
|
|
16
14
|
export declare function createRouteStaticDataSnippet(opts: {
|
|
17
15
|
modernRouteId?: string;
|
|
18
16
|
loaderName?: string | null;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AppTools } from '@modern-js/app-tools/cli-config';
|
|
2
|
+
import type { CLIPluginAPI } from '@modern-js/plugin';
|
|
2
3
|
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
3
4
|
type RouteForCli = NestedRouteForCli | PageRoute;
|
|
4
5
|
export declare function generateTanstackRouterTypesSourceForEntry(opts: {
|
|
5
|
-
appContext:
|
|
6
|
+
appContext: Pick<ReturnType<CLIPluginAPI<AppTools>['getAppContext']>, 'srcDirectory' | 'internalSrcAlias'>;
|
|
6
7
|
entryName: string;
|
|
7
8
|
generatedDirName?: string;
|
|
8
9
|
routes: RouteForCli[];
|
|
@@ -11,4 +11,4 @@ export type RouterLifecycleContext = NativeRouterLifecycleContext & {
|
|
|
11
11
|
cleanup?: () => void | Promise<void>;
|
|
12
12
|
serverSnapshot?: InternalRouterServerSnapshot;
|
|
13
13
|
};
|
|
14
|
-
export { applyRouterRuntimeState, applyRouterServerPrepareResult,
|
|
14
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterServerSnapshot, getRouterRuntimeState, getRouterServerSnapshot, type RouterLifecyclePhase, } from '@modern-js/runtime-extensions/router-state';
|
|
@@ -39,6 +39,7 @@ type LoaderLikeContext = {
|
|
|
39
39
|
};
|
|
40
40
|
params?: Record<string, string>;
|
|
41
41
|
};
|
|
42
|
+
export declare function getLoaderSignal(ctx: LoaderLikeContext | undefined): AbortSignal;
|
|
42
43
|
export declare function getLoaderHref(ctx: LoaderLikeContext | undefined): string;
|
|
43
44
|
export declare function handleModernLoaderResult<LoaderResult>(result: LoaderResult): LoaderResult;
|
|
44
45
|
export declare function handleModernLoaderError(err: unknown): never;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RouterNavigationCapability } from '@modern-js/runtime-extensions/router-state';
|
|
2
|
+
import type { AnyRouter } from '@tanstack/react-router';
|
|
3
|
+
/** Native TanStack navigation, exposed through the provider contract. */
|
|
4
|
+
export declare function createTanstackNavigation(router: AnyRouter): RouterNavigationCapability;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { OnRenderPreparedFn, OnRequestEndFn } from '@modern-js/plugin/runtime';
|
|
1
2
|
import { type TInternalRuntimeContext } from '@modern-js/runtime/context';
|
|
2
3
|
import type { RouteObject } from '@modern-js/runtime-utils/router';
|
|
3
4
|
import type { RouterExtendsHooks } from './hooks.js';
|
|
5
|
+
import type { RouterLifecycleContext } from './lifecycle.js';
|
|
4
6
|
import type { RouterConfig } from './types.js';
|
|
5
7
|
type TanstackRouterRuntimeConfig = {
|
|
6
8
|
plugins?: TanstackRouterRuntimePlugin[];
|
|
@@ -12,6 +14,9 @@ export type TanstackRouterPluginAPI = {
|
|
|
12
14
|
getRuntimeConfig: () => TanstackRouterRuntimeConfig;
|
|
13
15
|
getHooks: () => RouterExtendsHooks;
|
|
14
16
|
onBeforeRender: (listener: (context: TInternalRuntimeContext, interrupt: RuntimeInterrupt) => unknown) => void;
|
|
17
|
+
onRenderPrepared: (listener: OnRenderPreparedFn<TInternalRuntimeContext>) => void;
|
|
18
|
+
onRequestEnd: (listener: OnRequestEndFn<TInternalRuntimeContext>) => void;
|
|
19
|
+
onAfterCreateRouter: (listener: (event: RouterLifecycleContext) => void) => void;
|
|
15
20
|
wrapRoot: (listener: (App: any) => any) => void;
|
|
16
21
|
[key: string]: any;
|
|
17
22
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { AnyRouter } from '@tanstack/react-router';
|
|
2
2
|
import type { TanstackRouterWithServerSsr } from './ssrTypes.js';
|
|
3
|
-
export declare function waitForRouterSerialization(tanstackRouter: TanstackRouterWithServerSsr): Promise<void>;
|
|
4
3
|
export declare function routerManagedTagsToHtml(tags: unknown): string[];
|
|
5
4
|
export declare function createGetSsrHref(request: Request): string;
|
|
6
5
|
export declare function collectRouterErrors(tanstackRouter: AnyRouter): Record<string, unknown> | undefined;
|
|
@@ -28,13 +28,6 @@ type RouterRouteWithOptions = {
|
|
|
28
28
|
};
|
|
29
29
|
export type TanstackRouterWithServerSsr = AnyRouter & {
|
|
30
30
|
routesById?: Record<string, RouterRouteWithOptions>;
|
|
31
|
-
serverSsr?: {
|
|
32
|
-
cleanup?: () => void;
|
|
33
|
-
dehydrate?: () => Promise<void> | void;
|
|
34
|
-
isSerializationFinished?: () => boolean;
|
|
35
|
-
onSerializationFinished?: (listener: () => void) => void;
|
|
36
|
-
takeBufferedScripts?: () => unknown;
|
|
37
|
-
};
|
|
38
31
|
state: AnyRouter['state'] & {
|
|
39
32
|
matches?: unknown;
|
|
40
33
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type RouteShape = {
|
|
2
|
+
id?: string;
|
|
3
|
+
file?: string;
|
|
4
|
+
path?: string;
|
|
5
|
+
index?: boolean;
|
|
6
|
+
isRoot?: boolean;
|
|
7
|
+
children?: RouteShape[];
|
|
8
|
+
};
|
|
9
|
+
/** Browser-safe structure shared by the executable tree and concrete TS emitter. */
|
|
10
|
+
export type RouteDescriptor<T extends RouteShape> = {
|
|
11
|
+
source: T;
|
|
12
|
+
location: {
|
|
13
|
+
id: string;
|
|
14
|
+
path?: never;
|
|
15
|
+
} | {
|
|
16
|
+
path: string;
|
|
17
|
+
id?: never;
|
|
18
|
+
};
|
|
19
|
+
hasSplat: boolean;
|
|
20
|
+
children: RouteDescriptor<T>[];
|
|
21
|
+
};
|
|
22
|
+
export declare function describeRouteTree<T extends RouteShape>(routes: T[]): {
|
|
23
|
+
root: T | undefined;
|
|
24
|
+
children: RouteDescriptor<T>[];
|
|
25
|
+
};
|
|
26
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bleedingdev/modern-js-plugin-tanstack",
|
|
3
3
|
"description": "TanStack Router integration for Modern.js.",
|
|
4
|
-
"homepage": "https://github.com/
|
|
4
|
+
"homepage": "https://github.com/ultramodernjs/ultramodern.js#readme",
|
|
5
5
|
"bugs": {
|
|
6
|
-
"url": "https://github.com/
|
|
6
|
+
"url": "https://github.com/ultramodernjs/ultramodern.js/issues"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/
|
|
10
|
+
"url": "git+https://github.com/ultramodernjs/ultramodern.js.git",
|
|
11
11
|
"directory": "packages/runtime/plugin-tanstack"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"modern.js",
|
|
19
19
|
"tanstack-router"
|
|
20
20
|
],
|
|
21
|
-
"version": "3.9.
|
|
21
|
+
"version": "3.9.3-ultramodern.1",
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=20"
|
|
24
24
|
},
|
|
@@ -94,19 +94,19 @@
|
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@modern-js/i18n-runtime-extensions": "npm:@bleedingdev/modern-js-i18n-runtime-extensions@3.9.
|
|
98
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.
|
|
99
|
-
"@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.
|
|
100
|
-
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.
|
|
101
|
-
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.
|
|
102
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.
|
|
97
|
+
"@modern-js/i18n-runtime-extensions": "npm:@bleedingdev/modern-js-i18n-runtime-extensions@3.9.3-ultramodern.1",
|
|
98
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.1",
|
|
99
|
+
"@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.3-ultramodern.1",
|
|
100
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.1",
|
|
101
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.1",
|
|
102
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.1",
|
|
103
103
|
"@swc/helpers": "^0.5.23",
|
|
104
|
-
"@tanstack/react-router": "1.170.
|
|
105
|
-
"@tanstack/router-core": "1.171.
|
|
104
|
+
"@tanstack/react-router": "1.170.41",
|
|
105
|
+
"@tanstack/router-core": "1.171.34"
|
|
106
106
|
},
|
|
107
107
|
"peerDependencies": {
|
|
108
|
-
"@modern-js/app-tools": "3.9.
|
|
109
|
-
"@modern-js/runtime": "3.9.
|
|
108
|
+
"@modern-js/app-tools": "3.9.3-ultramodern.1",
|
|
109
|
+
"@modern-js/runtime": "3.9.3-ultramodern.1",
|
|
110
110
|
"react": "^19.2.8",
|
|
111
111
|
"react-dom": "^19.2.8",
|
|
112
112
|
"react-server-dom-rspack": "0.1.0"
|
|
@@ -117,20 +117,19 @@
|
|
|
117
117
|
}
|
|
118
118
|
},
|
|
119
119
|
"devDependencies": {
|
|
120
|
-
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.
|
|
121
|
-
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.
|
|
122
|
-
"@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.
|
|
123
|
-
"@rslib/core": "1.0.
|
|
120
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.3-ultramodern.1",
|
|
121
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.3-ultramodern.1",
|
|
122
|
+
"@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.3-ultramodern.1",
|
|
123
|
+
"@rslib/core": "1.0.3",
|
|
124
124
|
"@scripts/rstest-config": "2.66.0",
|
|
125
|
-
"@tanstack/history": "1.162.
|
|
125
|
+
"@tanstack/history": "1.162.4",
|
|
126
126
|
"@testing-library/react": "^16.3.3",
|
|
127
127
|
"@tsconfig/strictest": "2.0.8",
|
|
128
|
-
"@types/node": "^26.
|
|
129
|
-
"@types/react": "^19.
|
|
130
|
-
"@types/react-dom": "^19.
|
|
131
|
-
"
|
|
132
|
-
"react": "^19.
|
|
133
|
-
"react-dom": "^19.2.8",
|
|
128
|
+
"@types/node": "^26.6.3",
|
|
129
|
+
"@types/react": "^19.3.0",
|
|
130
|
+
"@types/react-dom": "^19.3.0",
|
|
131
|
+
"react": "^19.3.0",
|
|
132
|
+
"react-dom": "^19.3.0",
|
|
134
133
|
"react-server-dom-rspack": "0.1.0"
|
|
135
134
|
},
|
|
136
135
|
"sideEffects": [
|
|
@@ -150,9 +149,16 @@
|
|
|
150
149
|
"publishConfig": {
|
|
151
150
|
"access": "public"
|
|
152
151
|
},
|
|
152
|
+
"files": [
|
|
153
|
+
"dist",
|
|
154
|
+
"src"
|
|
155
|
+
],
|
|
153
156
|
"scripts": {
|
|
154
157
|
"dev": "rslib build --watch",
|
|
155
158
|
"build": "rslib build",
|
|
156
|
-
"test": "rstest
|
|
159
|
+
"test": "rstest"
|
|
160
|
+
},
|
|
161
|
+
"ultramodern": {
|
|
162
|
+
"sourceName": "@modern-js/plugin-tanstack"
|
|
157
163
|
}
|
|
158
164
|
}
|
package/src/cli/artifacts.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
// @effect-diagnostics asyncFunction:off nodeBuiltinImport:off strictBooleanExpressions:off processEnv:off processEnvInEffect:off
|
|
2
2
|
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import type {
|
|
4
|
+
import type { AppTools } from '@modern-js/app-tools/cli-config';
|
|
5
|
+
import type { CLIPluginAPI } from '@modern-js/plugin';
|
|
5
6
|
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
6
7
|
import { fs } from '@modern-js/utils';
|
|
7
8
|
|
|
9
|
+
import {
|
|
10
|
+
findRouteMetaFiles,
|
|
11
|
+
ROUTE_METADATA_MANIFEST_FILE_NAME,
|
|
12
|
+
ROUTE_METADATA_MANIFEST_HEADER,
|
|
13
|
+
renderRouteMetadataManifest,
|
|
14
|
+
} from './routeMetadata';
|
|
8
15
|
import {
|
|
9
16
|
collectCanonicalRoutesForEntry,
|
|
10
17
|
generateTanstackRouterTypesSourceForEntry,
|
|
@@ -108,7 +115,10 @@ export async function writeTanstackRegisterFile(opts: {
|
|
|
108
115
|
}
|
|
109
116
|
|
|
110
117
|
export async function writeTanstackRouterTypesForEntries(opts: {
|
|
111
|
-
appContext:
|
|
118
|
+
appContext: Pick<
|
|
119
|
+
ReturnType<CLIPluginAPI<AppTools>['getAppContext']>,
|
|
120
|
+
'srcDirectory' | 'internalSrcAlias' | 'entrypoints'
|
|
121
|
+
>;
|
|
112
122
|
generatedDirName?: string;
|
|
113
123
|
routesByEntry: Record<string, (NestedRouteForCli | PageRoute)[]>;
|
|
114
124
|
/**
|
|
@@ -193,16 +203,52 @@ export async function writeTanstackRouterTypesForEntries(opts: {
|
|
|
193
203
|
}
|
|
194
204
|
|
|
195
205
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
* Writes `src/routes/ultramodern-route-metadata.ts` from the `route.meta.ts`
|
|
207
|
+
* files below `src/routes`. Reads only the file system, never the app config.
|
|
208
|
+
*/
|
|
209
|
+
export async function writeRouteMetadataManifest(opts: {
|
|
210
|
+
appDirectory: string;
|
|
211
|
+
}): Promise<void> {
|
|
212
|
+
const routesDirectory = path.join(opts.appDirectory, 'src', 'routes');
|
|
213
|
+
const manifestPath = path.join(
|
|
214
|
+
routesDirectory,
|
|
215
|
+
ROUTE_METADATA_MANIFEST_FILE_NAME,
|
|
216
|
+
);
|
|
217
|
+
const manifest = renderRouteMetadataManifest(
|
|
218
|
+
await findRouteMetaFiles(routesDirectory),
|
|
219
|
+
);
|
|
220
|
+
if (manifest !== null) {
|
|
221
|
+
await writeFileIfChanged(manifestPath, manifest);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const previous = (await fs.pathExists(manifestPath))
|
|
225
|
+
? await fs.readFile(manifestPath, 'utf-8')
|
|
226
|
+
: null;
|
|
227
|
+
// No valid manifest exists without routes (its namespace comes from them),
|
|
228
|
+
// and the app config imports it, so the app cannot load in this state.
|
|
229
|
+
if (previous?.startsWith(`${ROUTE_METADATA_MANIFEST_HEADER}\n`)) {
|
|
230
|
+
throw new Error(
|
|
231
|
+
`[plugin-tanstack] ${manifestPath} is generated from route.meta.ts files, but none remain below ${routesDirectory}. ` +
|
|
232
|
+
'Restore at least one route.meta.ts that exports routeMeta, or delete the manifest together with its imports.',
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Headless regeneration of the route metadata manifest and of `router.gen.ts` /
|
|
239
|
+
* `register.gen.d.ts` for a generated app, without running a full dev/build.
|
|
240
|
+
* Drives the app-tools analyze `onPrepare` (which fires `generateEntryCode`)
|
|
241
|
+
* and returns before any bundling — the app's own registered plugin-tanstack
|
|
242
|
+
* writes the router artifacts via its `generateEntryCode` subscriber. Reuses
|
|
243
|
+
* the exact hook dev/build use, so there is no scanning drift.
|
|
201
244
|
*/
|
|
202
245
|
export async function generateTanstackRouteArtifacts(opts: {
|
|
203
246
|
appDirectory: string;
|
|
204
247
|
version?: string;
|
|
205
248
|
}): Promise<void> {
|
|
249
|
+
// The app config imports the manifest. Writing it first means a manifest
|
|
250
|
+
// that still imports a deleted route.meta.ts cannot fail the config load.
|
|
251
|
+
await writeRouteMetadataManifest(opts);
|
|
206
252
|
const [{ createRunOptions }, { cli }, utils] = await Promise.all([
|
|
207
253
|
import('@modern-js/app-tools/cli/run'),
|
|
208
254
|
import('@modern-js/plugin/cli'),
|
|
@@ -251,5 +297,10 @@ export async function generateTanstackRouteArtifacts(opts: {
|
|
|
251
297
|
internalPlugins: (utils as { INTERNAL_RUNTIME_PLUGINS: unknown })
|
|
252
298
|
.INTERNAL_RUNTIME_PLUGINS as never,
|
|
253
299
|
});
|
|
254
|
-
await cli.init({ ...runOptions, command: 'build' });
|
|
300
|
+
const { appContext } = await cli.init({ ...runOptions, command: 'build' });
|
|
301
|
+
// Preparation owns the artifact writes; there is no dev server or bundler
|
|
302
|
+
// phase after it. Release plugin resources before the headless caller exits.
|
|
303
|
+
// Failed initialization propagates unchanged: it has not returned a context
|
|
304
|
+
// whose lifecycle this caller can close.
|
|
305
|
+
await appContext.hooks.onBeforeExit.call();
|
|
255
306
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ import path from 'node:path';
|
|
|
3
3
|
import type {
|
|
4
4
|
AppNormalizedConfig,
|
|
5
5
|
AppTools,
|
|
6
|
-
AppToolsContext,
|
|
7
6
|
CliPlugin,
|
|
8
7
|
} from '@modern-js/app-tools';
|
|
9
8
|
import type { CLIPluginAPI } from '@modern-js/plugin';
|
|
@@ -15,7 +14,6 @@ import type {
|
|
|
15
14
|
} from '@modern-js/types';
|
|
16
15
|
import {
|
|
17
16
|
filterRoutesForServer,
|
|
18
|
-
fs,
|
|
19
17
|
NESTED_ROUTE_SPEC_FILE,
|
|
20
18
|
} from '@modern-js/utils';
|
|
21
19
|
import { writeTanstackRouterTypesForEntries } from './artifacts';
|
|
@@ -23,9 +21,14 @@ import {
|
|
|
23
21
|
createTanstackRsbuildRouteSplittingProfile,
|
|
24
22
|
type TanstackRouteCodeSplittingOption,
|
|
25
23
|
} from './routeSplitting';
|
|
24
|
+
import {
|
|
25
|
+
createTanstackRscRouteLayerPlugin,
|
|
26
|
+
TANSTACK_SERVER_ROUTES_FILE,
|
|
27
|
+
} from './rscRouteLayer';
|
|
26
28
|
|
|
27
29
|
export {
|
|
28
30
|
generateTanstackRouteArtifacts,
|
|
31
|
+
writeRouteMetadataManifest,
|
|
29
32
|
writeTanstackRegisterFile,
|
|
30
33
|
writeTanstackRouterTypesForEntries,
|
|
31
34
|
} from './artifacts';
|
|
@@ -239,6 +242,16 @@ export function tanstackRouterPlugin(
|
|
|
239
242
|
|
|
240
243
|
api.config(() => ({
|
|
241
244
|
...routeSplittingProfile.defaultConfig,
|
|
245
|
+
builderPlugins: [
|
|
246
|
+
createTanstackRscRouteLayerPlugin(() => ({
|
|
247
|
+
entryNames: api
|
|
248
|
+
.getAppContext()
|
|
249
|
+
.entrypoints.filter(isTanstackEntrypoint)
|
|
250
|
+
.map(entrypoint => entrypoint.entryName),
|
|
251
|
+
internalDirectory: api.getAppContext().internalDirectory,
|
|
252
|
+
rsc: api.getNormalizedConfig().server.rsc,
|
|
253
|
+
})),
|
|
254
|
+
],
|
|
242
255
|
source: {
|
|
243
256
|
include: [
|
|
244
257
|
// TanStack Router and its runtime deps ship modern syntax and
|
|
@@ -282,7 +295,7 @@ export function tanstackRouterPlugin(
|
|
|
282
295
|
hydrateRscClientRoutes: true,
|
|
283
296
|
includeRouteServerLoadersInSsrEntry: false,
|
|
284
297
|
isolateRouteDataInRscLayer: true,
|
|
285
|
-
serverRoutesFileName:
|
|
298
|
+
serverRoutesFileName: TANSTACK_SERVER_ROUTES_FILE,
|
|
286
299
|
},
|
|
287
300
|
);
|
|
288
301
|
|
|
@@ -312,7 +325,7 @@ export function tanstackRouterPlugin(
|
|
|
312
325
|
hydrateRscClientRoutes: true,
|
|
313
326
|
includeRouteServerLoadersInSsrEntry: false,
|
|
314
327
|
isolateRouteDataInRscLayer: true,
|
|
315
|
-
serverRoutesFileName:
|
|
328
|
+
serverRoutesFileName: TANSTACK_SERVER_ROUTES_FILE,
|
|
316
329
|
},
|
|
317
330
|
);
|
|
318
331
|
|