@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.12 → 3.2.0-ultramodern.121
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/index.js +89 -31
- package/dist/cjs/cli/routeSplitting.js +55 -0
- package/dist/cjs/cli/tanstackTypes.js +172 -170
- package/dist/cjs/cli.js +12 -8
- package/dist/cjs/runtime/basepathRewrite.js +12 -8
- package/dist/cjs/runtime/dataMutation.js +9 -5
- package/dist/cjs/runtime/hooks.js +20 -19
- package/dist/cjs/runtime/hydrationBoundary.js +48 -0
- package/dist/cjs/runtime/index.js +79 -35
- package/dist/cjs/runtime/lifecycle.js +21 -91
- package/dist/cjs/runtime/loaderBridge.js +173 -0
- package/dist/cjs/runtime/outlet.js +58 -0
- package/dist/cjs/runtime/plugin.js +195 -114
- package/dist/cjs/runtime/plugin.node.js +45 -45
- package/dist/cjs/runtime/plugin.worker.js +53 -0
- package/dist/cjs/runtime/pluginCore.js +55 -0
- package/dist/cjs/runtime/prefetchLink.js +10 -6
- package/dist/cjs/runtime/register.js +56 -0
- package/dist/cjs/runtime/routeTree.js +74 -207
- package/dist/cjs/runtime/router.js +41 -0
- package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
- package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
- package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
- package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
- package/dist/cjs/runtime/rsc/client.js +9 -5
- package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
- package/dist/cjs/runtime/rsc/index.js +9 -5
- package/dist/cjs/runtime/rsc/payloadRouter.js +44 -6
- package/dist/cjs/runtime/rsc/server.js +9 -5
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
- package/dist/cjs/runtime/rsc/symbols.js +20 -15
- package/dist/cjs/runtime/state.js +45 -0
- package/dist/cjs/runtime/types.js +31 -1
- package/dist/cjs/runtime/utils.js +9 -10
- package/dist/cjs/runtime.js +9 -5
- package/dist/esm/cli/index.mjs +75 -27
- package/dist/esm/cli/routeSplitting.mjs +14 -0
- package/dist/esm/cli/tanstackTypes.mjs +158 -160
- package/dist/esm/runtime/hooks.mjs +1 -8
- package/dist/esm/runtime/hydrationBoundary.mjs +10 -0
- package/dist/esm/runtime/index.mjs +5 -2
- package/dist/esm/runtime/lifecycle.mjs +1 -82
- package/dist/esm/runtime/loaderBridge.mjs +114 -0
- package/dist/esm/runtime/outlet.mjs +17 -0
- package/dist/esm/runtime/plugin.mjs +191 -114
- package/dist/esm/runtime/plugin.node.mjs +40 -44
- package/dist/esm/runtime/plugin.worker.mjs +1 -0
- package/dist/esm/runtime/pluginCore.mjs +14 -0
- package/dist/esm/runtime/prefetchLink.mjs +1 -1
- package/dist/esm/runtime/register.mjs +18 -0
- package/dist/esm/runtime/routeTree.mjs +59 -193
- package/dist/esm/runtime/router.mjs +2 -0
- package/dist/esm/runtime/rsc/payloadRouter.mjs +35 -1
- package/dist/esm/runtime/state.mjs +7 -0
- package/dist/esm/runtime/types.mjs +7 -0
- package/dist/esm/runtime/utils.mjs +0 -5
- package/dist/esm-node/cli/index.mjs +75 -27
- package/dist/esm-node/cli/routeSplitting.mjs +15 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +158 -160
- package/dist/esm-node/runtime/hooks.mjs +1 -8
- package/dist/esm-node/runtime/hydrationBoundary.mjs +11 -0
- package/dist/esm-node/runtime/index.mjs +5 -2
- package/dist/esm-node/runtime/lifecycle.mjs +1 -82
- package/dist/esm-node/runtime/loaderBridge.mjs +115 -0
- package/dist/esm-node/runtime/outlet.mjs +18 -0
- package/dist/esm-node/runtime/plugin.mjs +191 -114
- package/dist/esm-node/runtime/plugin.node.mjs +40 -44
- package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
- package/dist/esm-node/runtime/pluginCore.mjs +15 -0
- package/dist/esm-node/runtime/prefetchLink.mjs +1 -1
- package/dist/esm-node/runtime/register.mjs +19 -0
- package/dist/esm-node/runtime/routeTree.mjs +59 -193
- package/dist/esm-node/runtime/router.mjs +3 -0
- package/dist/esm-node/runtime/rsc/payloadRouter.mjs +35 -1
- package/dist/esm-node/runtime/state.mjs +8 -0
- package/dist/esm-node/runtime/types.mjs +7 -0
- package/dist/esm-node/runtime/utils.mjs +0 -5
- package/dist/types/cli/index.d.ts +14 -1
- package/dist/types/cli/routeSplitting.d.ts +20 -0
- package/dist/types/cli/tanstackTypes.d.ts +21 -1
- package/dist/types/runtime/hooks.d.ts +8 -33
- package/dist/types/runtime/hydrationBoundary.d.ts +2 -0
- package/dist/types/runtime/index.d.ts +8 -3
- package/dist/types/runtime/lifecycle.d.ts +7 -22
- package/dist/types/runtime/loaderBridge.d.ts +48 -0
- package/dist/types/runtime/outlet.d.ts +2 -0
- package/dist/types/runtime/plugin.d.ts +2 -15
- package/dist/types/runtime/plugin.node.d.ts +2 -15
- package/dist/types/runtime/plugin.worker.d.ts +1 -0
- package/dist/types/runtime/pluginCore.d.ts +21 -0
- package/dist/types/runtime/register.d.ts +9 -0
- package/dist/types/runtime/routeTree.d.ts +0 -2
- package/dist/types/runtime/router.d.ts +14 -0
- package/dist/types/runtime/state.d.ts +16 -0
- package/dist/types/runtime/types.d.ts +14 -53
- package/package.json +42 -40
- package/rstest.config.mts +6 -0
- package/src/cli/index.ts +162 -23
- package/src/cli/routeSplitting.ts +43 -0
- package/src/cli/tanstackTypes.ts +331 -187
- package/src/runtime/hooks.ts +10 -27
- package/src/runtime/hydrationBoundary.tsx +12 -0
- package/src/runtime/index.tsx +17 -7
- package/src/runtime/lifecycle.ts +16 -151
- package/src/runtime/loaderBridge.ts +257 -0
- package/src/runtime/outlet.tsx +48 -0
- package/src/runtime/plugin.node.tsx +72 -85
- package/src/runtime/plugin.tsx +361 -206
- package/src/runtime/plugin.worker.tsx +4 -0
- package/src/runtime/pluginCore.ts +48 -0
- package/src/runtime/prefetchLink.tsx +1 -1
- package/src/runtime/register.ts +58 -0
- package/src/runtime/routeTree.ts +163 -354
- package/src/runtime/router.ts +15 -0
- package/src/runtime/rsc/payloadRouter.ts +45 -2
- package/src/runtime/ssr-shim.d.ts +1 -3
- package/src/runtime/state.ts +29 -0
- package/src/runtime/types.ts +32 -66
- package/src/runtime/utils.tsx +3 -6
- package/tests/router/cli.test.ts +586 -5
- package/tests/router/fastDefaults.test.ts +25 -0
- package/tests/router/hooks.test.ts +26 -0
- package/tests/router/hydrationBoundary.test.tsx +23 -0
- package/tests/router/loaderBridge.test.ts +211 -0
- package/tests/router/packageSurface.test.ts +24 -0
- package/tests/router/prefetchLink.test.tsx +43 -7
- package/tests/router/register.test.ts +46 -0
- package/tests/router/routeTree.test.ts +381 -81
- package/tests/router/rsc.test.tsx +70 -0
- package/tests/router/tanstackTypes.test.ts +573 -1
- package/dist/cjs/runtime/DefaultNotFound.js +0 -47
- package/dist/esm/runtime/DefaultNotFound.mjs +0 -13
- package/dist/esm-node/runtime/DefaultNotFound.mjs +0 -14
- package/dist/types/runtime/DefaultNotFound.d.ts +0 -2
- package/src/runtime/DefaultNotFound.tsx +0 -15
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import "./register.mjs";
|
|
2
3
|
export * from "@tanstack/react-router";
|
|
3
|
-
export { useMatch } from "@tanstack/react-router";
|
|
4
4
|
export { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
|
|
5
|
+
export { createRouteStaticData, isAbsoluteUrl, modernLoaderToTanstack, throwTanstackRedirect } from "./loaderBridge.mjs";
|
|
6
|
+
export { Outlet } from "./outlet.mjs";
|
|
5
7
|
export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
|
|
6
8
|
export { Link, NavLink } from "./prefetchLink.mjs";
|
|
7
|
-
export {
|
|
9
|
+
export { getTanstackRouterState } from "./state.mjs";
|
|
10
|
+
export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
|
|
@@ -1,83 +1,2 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
|
|
3
|
-
if (state.hydrationScripts?.length) return state.hydrationScripts;
|
|
4
|
-
return state.hydrationScript ? [
|
|
5
|
-
state.hydrationScript
|
|
6
|
-
] : void 0;
|
|
7
|
-
}
|
|
8
|
-
function getMatchedRouteIdsFromMatches(matches) {
|
|
9
|
-
const routeIds = matches?.map((match)=>match.assetRouteId ?? match.routeId).filter((routeId)=>'string' == typeof routeId);
|
|
10
|
-
return routeIds?.length ? routeIds : void 0;
|
|
11
|
-
}
|
|
12
|
-
function createRouterServerSnapshot(state) {
|
|
13
|
-
const hydrationScripts = toHydrationScripts(state);
|
|
14
|
-
const matchedRouteIds = state.matchedRouteIds ?? getMatchedRouteIdsFromMatches(state.matches);
|
|
15
|
-
return {
|
|
16
|
-
...state,
|
|
17
|
-
...hydrationScripts?.length ? {
|
|
18
|
-
hydrationScript: state.hydrationScript ?? hydrationScripts[0],
|
|
19
|
-
hydrationScripts
|
|
20
|
-
} : {},
|
|
21
|
-
...matchedRouteIds ? {
|
|
22
|
-
matchedRouteIds
|
|
23
|
-
} : {}
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function createRouterRuntimeState(state) {
|
|
27
|
-
const hasSnapshotState = Boolean(state.serverSnapshot) || Boolean(state.hydrationScript) || Boolean(state.hydrationScripts?.length) || Boolean(state.matchedRouteIds?.length) || Boolean(state.matches?.length);
|
|
28
|
-
const serverSnapshot = state.serverSnapshot ? createRouterServerSnapshot({
|
|
29
|
-
...state.serverSnapshot,
|
|
30
|
-
framework: state.serverSnapshot.framework ?? state.framework,
|
|
31
|
-
basename: state.serverSnapshot.basename ?? state.basename,
|
|
32
|
-
hydrationScript: state.serverSnapshot.hydrationScript ?? state.hydrationScript,
|
|
33
|
-
hydrationScripts: state.serverSnapshot.hydrationScripts ?? state.hydrationScripts,
|
|
34
|
-
matchedRouteIds: state.serverSnapshot.matchedRouteIds ?? state.matchedRouteIds,
|
|
35
|
-
matches: state.serverSnapshot.matches ?? state.matches
|
|
36
|
-
}) : hasSnapshotState ? createRouterServerSnapshot({
|
|
37
|
-
framework: state.framework,
|
|
38
|
-
basename: state.basename,
|
|
39
|
-
hydrationScript: state.hydrationScript,
|
|
40
|
-
hydrationScripts: state.hydrationScripts,
|
|
41
|
-
matchedRouteIds: state.matchedRouteIds,
|
|
42
|
-
matches: state.matches
|
|
43
|
-
}) : void 0;
|
|
44
|
-
const hydrationScripts = toHydrationScripts({
|
|
45
|
-
hydrationScript: state.hydrationScript ?? serverSnapshot?.hydrationScript,
|
|
46
|
-
hydrationScripts: state.hydrationScripts ?? serverSnapshot?.hydrationScripts
|
|
47
|
-
});
|
|
48
|
-
const matchedRouteIds = state.matchedRouteIds ?? serverSnapshot?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(state.matches);
|
|
49
|
-
return {
|
|
50
|
-
...state,
|
|
51
|
-
...hydrationScripts?.length ? {
|
|
52
|
-
hydrationScript: state.hydrationScript ?? hydrationScripts[0],
|
|
53
|
-
hydrationScripts
|
|
54
|
-
} : {},
|
|
55
|
-
...matchedRouteIds ? {
|
|
56
|
-
matchedRouteIds
|
|
57
|
-
} : {},
|
|
58
|
-
...serverSnapshot ? {
|
|
59
|
-
serverSnapshot
|
|
60
|
-
} : {}
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
function applyRouterRuntimeState(runtimeContext, state) {
|
|
64
|
-
const normalized = createRouterRuntimeState(state);
|
|
65
|
-
const mutableRuntimeContext = runtimeContext;
|
|
66
|
-
mutableRuntimeContext.routerFramework = normalized.framework;
|
|
67
|
-
mutableRuntimeContext.routerInstance = normalized.instance;
|
|
68
|
-
mutableRuntimeContext.routerHydrationScript = normalized.hydrationScript;
|
|
69
|
-
mutableRuntimeContext.routerMatchedRouteIds = normalized.matchedRouteIds;
|
|
70
|
-
mutableRuntimeContext.routerRuntime = normalized;
|
|
71
|
-
if (normalized.serverSnapshot) mutableRuntimeContext.routerServerSnapshot = normalized.serverSnapshot;
|
|
72
|
-
return runtimeContext;
|
|
73
|
-
}
|
|
74
|
-
function applyRouterServerPrepareResult(runtimeContext, result) {
|
|
75
|
-
const state = createRouterRuntimeState({
|
|
76
|
-
...result.state,
|
|
77
|
-
cleanup: result.cleanup ?? result.state.cleanup,
|
|
78
|
-
serverSnapshot: result.snapshot ?? result.state.serverSnapshot
|
|
79
|
-
});
|
|
80
|
-
applyRouterRuntimeState(runtimeContext, state);
|
|
81
|
-
return runtimeContext;
|
|
82
|
-
}
|
|
83
|
-
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot };
|
|
2
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot, getRouterRuntimeState, getRouterServerSnapshot } from "@modern-js/runtime/context";
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { notFound, redirect } from "@tanstack/react-router";
|
|
3
|
+
function isResponse(value) {
|
|
4
|
+
const record = value;
|
|
5
|
+
return null != record && 'object' == typeof record && 'number' == typeof record.status && 'object' == typeof record.headers;
|
|
6
|
+
}
|
|
7
|
+
const redirectStatusCodes = new Set([
|
|
8
|
+
301,
|
|
9
|
+
302,
|
|
10
|
+
303,
|
|
11
|
+
307,
|
|
12
|
+
308
|
|
13
|
+
]);
|
|
14
|
+
function isRedirectResponse(res) {
|
|
15
|
+
return redirectStatusCodes.has(res.status);
|
|
16
|
+
}
|
|
17
|
+
function isTanstackRedirect(value) {
|
|
18
|
+
return isResponse(value) && 'object' == typeof value.options;
|
|
19
|
+
}
|
|
20
|
+
function isAbsoluteUrl(value) {
|
|
21
|
+
try {
|
|
22
|
+
new URL(value);
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function throwTanstackRedirect(location) {
|
|
29
|
+
const target = location || '/';
|
|
30
|
+
if (isAbsoluteUrl(target)) throw redirect({
|
|
31
|
+
href: target
|
|
32
|
+
});
|
|
33
|
+
throw redirect({
|
|
34
|
+
to: target
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function mapSplatParamsForModernLoader(params, hasSplat) {
|
|
38
|
+
if (!hasSplat) return params;
|
|
39
|
+
const { _splat, ...rest } = params;
|
|
40
|
+
if (void 0 !== _splat) return {
|
|
41
|
+
...rest,
|
|
42
|
+
'*': _splat
|
|
43
|
+
};
|
|
44
|
+
return rest;
|
|
45
|
+
}
|
|
46
|
+
function createRouteStaticData(opts) {
|
|
47
|
+
const staticData = {};
|
|
48
|
+
if ('string' == typeof opts.modernRouteId && opts.modernRouteId.length > 0) staticData.modernRouteId = opts.modernRouteId;
|
|
49
|
+
if (void 0 !== opts.modernRouteLoader) staticData.modernRouteLoader = opts.modernRouteLoader;
|
|
50
|
+
if (void 0 !== opts.modernRouteAction) staticData.modernRouteAction = opts.modernRouteAction;
|
|
51
|
+
return staticData;
|
|
52
|
+
}
|
|
53
|
+
function getLoaderSignal(ctx) {
|
|
54
|
+
const abortSignal = ctx?.abortController?.signal;
|
|
55
|
+
if (abortSignal instanceof AbortSignal) return abortSignal;
|
|
56
|
+
if (ctx?.signal instanceof AbortSignal) return ctx.signal;
|
|
57
|
+
return new AbortController().signal;
|
|
58
|
+
}
|
|
59
|
+
function getLoaderHref(ctx) {
|
|
60
|
+
if ('string' == typeof ctx?.location) return ctx.location;
|
|
61
|
+
const publicHref = ctx?.location?.publicHref;
|
|
62
|
+
if ('string' == typeof publicHref) return publicHref;
|
|
63
|
+
const href = ctx?.location?.href;
|
|
64
|
+
if ('string' == typeof href) return href;
|
|
65
|
+
const urlHref = ctx?.location?.url?.href;
|
|
66
|
+
return 'string' == typeof urlHref ? urlHref : '';
|
|
67
|
+
}
|
|
68
|
+
function getLoaderParams(ctx) {
|
|
69
|
+
return 'object' == typeof ctx?.params && null !== ctx.params ? ctx.params : {};
|
|
70
|
+
}
|
|
71
|
+
function handleModernLoaderResult(result) {
|
|
72
|
+
if (isResponse(result)) {
|
|
73
|
+
if (isRedirectResponse(result)) {
|
|
74
|
+
const location = result.headers.get('Location') ?? '/';
|
|
75
|
+
throwTanstackRedirect(location);
|
|
76
|
+
}
|
|
77
|
+
if (404 === result.status) throw notFound();
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
function handleModernLoaderError(err) {
|
|
82
|
+
if (isResponse(err)) {
|
|
83
|
+
if (isTanstackRedirect(err)) throw err;
|
|
84
|
+
if (isRedirectResponse(err)) {
|
|
85
|
+
const location = err.headers.get('Location') ?? '/';
|
|
86
|
+
throwTanstackRedirect(location);
|
|
87
|
+
}
|
|
88
|
+
if (404 === err.status) throw notFound();
|
|
89
|
+
}
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
function modernLoaderToTanstack(opts, modernLoader) {
|
|
93
|
+
return (rawCtx)=>{
|
|
94
|
+
const ctx = rawCtx;
|
|
95
|
+
try {
|
|
96
|
+
const signal = getLoaderSignal(ctx);
|
|
97
|
+
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
98
|
+
const href = getLoaderHref(ctx);
|
|
99
|
+
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
100
|
+
signal
|
|
101
|
+
}) : new Request(href, {
|
|
102
|
+
signal
|
|
103
|
+
});
|
|
104
|
+
const params = mapSplatParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
|
|
105
|
+
return Promise.resolve(modernLoader({
|
|
106
|
+
request,
|
|
107
|
+
params,
|
|
108
|
+
context: ctx?.context?.requestContext
|
|
109
|
+
})).then((result)=>handleModernLoaderResult(result)).catch(handleModernLoaderError);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
handleModernLoaderError(err);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export { createRouteStaticData, isAbsoluteUrl, isRedirectResponse, isResponse, isTanstackRedirect, mapSplatParamsForModernLoader, modernLoaderToTanstack, throwTanstackRedirect };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Outlet } from "@tanstack/react-router";
|
|
4
|
+
import { createElement, memo } from "react";
|
|
5
|
+
const outlet_Outlet = /*#__PURE__*/ memo(function() {
|
|
6
|
+
return /*#__PURE__*/ jsx(Outlet, {});
|
|
7
|
+
});
|
|
8
|
+
function withModernRouteMatchContext(component, _routeId) {
|
|
9
|
+
if (null == component) return component;
|
|
10
|
+
const Component = component;
|
|
11
|
+
const WrappedRouteComponent = (props)=>/*#__PURE__*/ createElement(Component, props);
|
|
12
|
+
const preloadable = component;
|
|
13
|
+
if ('function' == typeof preloadable.load) WrappedRouteComponent.load = preloadable.load.bind(preloadable);
|
|
14
|
+
if ('function' == typeof preloadable.preload) WrappedRouteComponent.preload = preloadable.preload.bind(preloadable);
|
|
15
|
+
else if ('function' == typeof preloadable.load) WrappedRouteComponent.preload = WrappedRouteComponent.load;
|
|
16
|
+
return WrappedRouteComponent;
|
|
17
|
+
}
|
|
18
|
+
export { outlet_Outlet as Outlet, withModernRouteMatchContext };
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import { InternalRuntimeContext, getGlobalEnableRsc
|
|
4
|
-
import { merge } from "@modern-js/runtime-utils/merge";
|
|
3
|
+
import { InternalRuntimeContext, getGlobalEnableRsc } from "@modern-js/runtime/context";
|
|
5
4
|
import { normalizePathname } from "@modern-js/runtime-utils/url";
|
|
6
5
|
import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
|
|
7
|
-
import {
|
|
6
|
+
import { hydrate } from "@tanstack/react-router/ssr/client";
|
|
7
|
+
import { useContext, useMemo } from "react";
|
|
8
8
|
import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import { routerProviderRegistryHooks } from "./hooks.mjs";
|
|
10
|
+
import { wrapTanstackSsrHydrationBoundary } from "./hydrationBoundary.mjs";
|
|
10
11
|
import { applyRouterRuntimeState } from "./lifecycle.mjs";
|
|
12
|
+
import { withModernRouteMatchContext } from "./outlet.mjs";
|
|
13
|
+
import { getFinalRouteConfig, getMergedRouterConfig } from "./pluginCore.mjs";
|
|
14
|
+
import { Link } from "./prefetchLink.mjs";
|
|
11
15
|
import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
|
|
12
16
|
import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
|
|
17
|
+
import { getModernTanstackRouterFastDefaults } from "./types.mjs";
|
|
13
18
|
import { createRouteObjectsFromConfig, urlJoin } from "./utils.mjs";
|
|
14
|
-
import * as __rspack_external_react from "react";
|
|
15
19
|
const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-subscribe');
|
|
16
20
|
const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-state');
|
|
17
21
|
function normalizeBase(b) {
|
|
@@ -39,133 +43,207 @@ function wrapRouterSubscribeWithBlockState(router, getBlockNavState) {
|
|
|
39
43
|
};
|
|
40
44
|
target[BLOCKING_SUBSCRIBE_SYMBOL] = true;
|
|
41
45
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
const routerHydrationRecords = new WeakMap();
|
|
47
|
+
const routeModulesKey = '_routeModules';
|
|
48
|
+
function pickRouteModuleComponent(routeModule, seen = new Set()) {
|
|
49
|
+
if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
|
|
50
|
+
if (!routeModule || 'object' != typeof routeModule) return;
|
|
51
|
+
if (seen.has(routeModule)) return;
|
|
52
|
+
seen.add(routeModule);
|
|
53
|
+
const module = routeModule;
|
|
54
|
+
for (const candidate of [
|
|
55
|
+
module.default,
|
|
56
|
+
module.Component
|
|
57
|
+
]){
|
|
58
|
+
const component = pickRouteModuleComponent(candidate, seen);
|
|
59
|
+
if (component) return component;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function getCachedRouteModule(routeId) {
|
|
63
|
+
if ("u" < typeof window) return;
|
|
64
|
+
return window[routeModulesKey]?.[routeId];
|
|
65
|
+
}
|
|
66
|
+
function preloadHydratedRouteComponents(router) {
|
|
67
|
+
const preloadableRouter = router;
|
|
68
|
+
const routesById = preloadableRouter.routesById || {};
|
|
69
|
+
const matches = preloadableRouter.stores.matches.get();
|
|
70
|
+
return Promise.all(matches.map((match)=>{
|
|
71
|
+
if (void 0 === match.routeId || '' === match.routeId) return;
|
|
72
|
+
const route = routesById[match.routeId];
|
|
73
|
+
const component = route?.options?.component;
|
|
74
|
+
const preload = component?.load || component?.preload;
|
|
75
|
+
if ('function' != typeof preload) return;
|
|
76
|
+
return Promise.resolve(preload.call(component)).then((routeModule)=>{
|
|
77
|
+
const modernRouteId = route?.options?.staticData?.modernRouteId;
|
|
78
|
+
const cachedRouteModule = 'string' == typeof modernRouteId && '' !== modernRouteId ? getCachedRouteModule(modernRouteId) : void 0;
|
|
79
|
+
const resolvedComponent = pickRouteModuleComponent(cachedRouteModule ?? routeModule);
|
|
80
|
+
if (void 0 !== resolvedComponent && 'string' == typeof modernRouteId && '' !== modernRouteId) route.options.component = withModernRouteMatchContext(resolvedComponent, modernRouteId);
|
|
81
|
+
});
|
|
82
|
+
})).then(()=>void 0);
|
|
83
|
+
}
|
|
84
|
+
function getTanstackSsrHydrationRecord(router) {
|
|
85
|
+
const existingHydrationRecord = routerHydrationRecords.get(router);
|
|
86
|
+
if (void 0 !== existingHydrationRecord) return existingHydrationRecord;
|
|
87
|
+
const hydrationRecord = {
|
|
88
|
+
promise: Promise.resolve(),
|
|
89
|
+
status: 'pending'
|
|
90
|
+
};
|
|
91
|
+
routerHydrationRecords.set(router, hydrationRecord);
|
|
92
|
+
try {
|
|
93
|
+
hydrationRecord.promise = hydrate(router).then((value)=>preloadHydratedRouteComponents(router).then(()=>value)).then((value)=>{
|
|
94
|
+
hydrationRecord.status = 'fulfilled';
|
|
95
|
+
return value;
|
|
96
|
+
}, (error)=>{
|
|
97
|
+
hydrationRecord.status = 'rejected';
|
|
98
|
+
hydrationRecord.error = error;
|
|
99
|
+
throw error;
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
hydrationRecord.status = 'rejected';
|
|
103
|
+
hydrationRecord.error = error;
|
|
104
|
+
hydrationRecord.promise = Promise.reject(error);
|
|
105
|
+
hydrationRecord.promise.catch(()=>{});
|
|
106
|
+
}
|
|
107
|
+
return hydrationRecord;
|
|
108
|
+
}
|
|
109
|
+
function getTanstackSsrHydrationPromise(router) {
|
|
110
|
+
return getTanstackSsrHydrationRecord(router).promise;
|
|
111
|
+
}
|
|
112
|
+
function hasTanstackSsrHydrationRecord(router) {
|
|
113
|
+
return routerHydrationRecords.has(router);
|
|
114
|
+
}
|
|
115
|
+
function ModernRouterClient({ router }) {
|
|
116
|
+
const hydrationRecord = getTanstackSsrHydrationRecord(router);
|
|
117
|
+
if ('rejected' === hydrationRecord.status) throw hydrationRecord.error;
|
|
118
|
+
return /*#__PURE__*/ jsx(RouterProvider, {
|
|
119
|
+
router: router
|
|
49
120
|
});
|
|
50
121
|
}
|
|
51
122
|
const tanstackRouterPlugin = (userConfig = {})=>{
|
|
52
123
|
const plugin = {
|
|
53
124
|
name: '@modern-js/plugin-router-tanstack',
|
|
54
|
-
registryHooks:
|
|
55
|
-
modifyRoutes: modifyRoutes,
|
|
56
|
-
onAfterCreateRouter: onAfterCreateRouter,
|
|
57
|
-
onAfterHydrateRouter: onAfterHydrateRouter,
|
|
58
|
-
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
59
|
-
onBeforeCreateRoutes: onBeforeCreateRoutes,
|
|
60
|
-
onBeforeHydrateRouter: onBeforeHydrateRouter
|
|
61
|
-
},
|
|
125
|
+
registryHooks: routerProviderRegistryHooks,
|
|
62
126
|
setup: (api)=>{
|
|
127
|
+
const hooks = api.getHooks();
|
|
128
|
+
let cachedRouteObjects;
|
|
129
|
+
let cachedRouteTree = null;
|
|
130
|
+
let cachedRouter = null;
|
|
131
|
+
let cachedRouterBasepath = null;
|
|
132
|
+
const getMergedConfig = ()=>getMergedRouterConfig(api, userConfig);
|
|
133
|
+
const getRouteObjects = ()=>{
|
|
134
|
+
if (void 0 !== cachedRouteObjects) return cachedRouteObjects;
|
|
135
|
+
const mergedConfig = getMergedConfig();
|
|
136
|
+
const { createRoutes } = mergedConfig;
|
|
137
|
+
const finalRouteConfig = getFinalRouteConfig(mergedConfig);
|
|
138
|
+
const routeObjects = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
|
|
139
|
+
routesConfig: finalRouteConfig
|
|
140
|
+
}) || [];
|
|
141
|
+
cachedRouteObjects = hooks.modifyRoutes.call(routeObjects);
|
|
142
|
+
return cachedRouteObjects;
|
|
143
|
+
};
|
|
144
|
+
const getRouteTree = ()=>{
|
|
145
|
+
if (cachedRouteTree) return cachedRouteTree;
|
|
146
|
+
const routeObjects = getRouteObjects();
|
|
147
|
+
if (!routeObjects.length) return null;
|
|
148
|
+
cachedRouteTree = createRouteTreeFromRouteObjects(routeObjects, {
|
|
149
|
+
rscPayloadRouter: getGlobalEnableRsc()
|
|
150
|
+
});
|
|
151
|
+
return cachedRouteTree;
|
|
152
|
+
};
|
|
153
|
+
const selectBasePath = (pathname)=>{
|
|
154
|
+
const { serverBase = [] } = getMergedConfig();
|
|
155
|
+
const match = serverBase.find((baseUrl)=>isSegmentPrefix(pathname, baseUrl));
|
|
156
|
+
return match || '/';
|
|
157
|
+
};
|
|
158
|
+
const getClientBasename = (runtimeContext)=>{
|
|
159
|
+
const { basename = '' } = getMergedConfig();
|
|
160
|
+
const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
|
|
161
|
+
return '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
|
|
162
|
+
};
|
|
163
|
+
const getRouter = (runtimeContext, _basename)=>{
|
|
164
|
+
const routeTree = getRouteTree();
|
|
165
|
+
if (!routeTree) return null;
|
|
166
|
+
const lifecycleContext = {
|
|
167
|
+
framework: 'tanstack',
|
|
168
|
+
phase: 'client-create',
|
|
169
|
+
routes: getRouteObjects(),
|
|
170
|
+
runtimeContext,
|
|
171
|
+
basename: _basename
|
|
172
|
+
};
|
|
173
|
+
hooks.onBeforeCreateRouter.call(lifecycleContext);
|
|
174
|
+
if (cachedRouter && cachedRouterBasepath === _basename) {
|
|
175
|
+
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
176
|
+
hooks.onAfterCreateRouter.call({
|
|
177
|
+
...lifecycleContext,
|
|
178
|
+
router: cachedRouter,
|
|
179
|
+
runtimeContext
|
|
180
|
+
});
|
|
181
|
+
return cachedRouter;
|
|
182
|
+
}
|
|
183
|
+
const mergedConfig = getMergedConfig();
|
|
184
|
+
const { supportHtml5History = true } = mergedConfig;
|
|
185
|
+
const history = supportHtml5History ? createBrowserHistory() : createHashHistory();
|
|
186
|
+
const rewrite = createModernBasepathRewrite(_basename);
|
|
187
|
+
const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
|
|
188
|
+
cachedRouter = createRouter({
|
|
189
|
+
...getModernTanstackRouterFastDefaults(mergedConfig),
|
|
190
|
+
routeTree,
|
|
191
|
+
basepath: '/',
|
|
192
|
+
rewrite,
|
|
193
|
+
history,
|
|
194
|
+
context: {},
|
|
195
|
+
...serializationAdapters ? {
|
|
196
|
+
serializationAdapters
|
|
197
|
+
} : {}
|
|
198
|
+
});
|
|
199
|
+
cachedRouterBasepath = _basename;
|
|
200
|
+
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
201
|
+
hooks.onAfterCreateRouter.call({
|
|
202
|
+
...lifecycleContext,
|
|
203
|
+
router: cachedRouter,
|
|
204
|
+
runtimeContext
|
|
205
|
+
});
|
|
206
|
+
return cachedRouter;
|
|
207
|
+
};
|
|
63
208
|
api.onBeforeRender((context)=>{
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
if ("u" > typeof window && window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
|
|
209
|
+
const mergedConfig = getMergedConfig();
|
|
210
|
+
if ("u" > typeof window && void 0 !== window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
|
|
67
211
|
const { ssrContext } = context;
|
|
68
212
|
const currentPathname = normalizePathname(window.location.pathname);
|
|
69
|
-
const initialPathname = ssrContext?.request?.pathname
|
|
70
|
-
if (initialPathname && initialPathname !== currentPathname) {
|
|
213
|
+
const initialPathname = 'string' == typeof ssrContext?.request?.pathname ? normalizePathname(ssrContext.request.pathname) : void 0;
|
|
214
|
+
if (void 0 !== initialPathname && '' !== initialPathname && initialPathname !== currentPathname) {
|
|
71
215
|
const errorMsg = `The initial URL ${initialPathname} and the URL ${currentPathname} to be hydrated do not match, reload.`;
|
|
72
216
|
console.error(errorMsg);
|
|
73
217
|
window.location.reload();
|
|
74
218
|
}
|
|
75
219
|
}
|
|
76
220
|
context.router = {
|
|
221
|
+
Link: Link,
|
|
77
222
|
useMatches: useMatches,
|
|
78
223
|
useLocation: useLocation,
|
|
79
224
|
useNavigate: useNavigate,
|
|
80
225
|
useRouter: useRouter
|
|
81
226
|
};
|
|
227
|
+
const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
|
|
228
|
+
if (hasSSRBootstrap && getRouteObjects().length > 0) {
|
|
229
|
+
const runtimeContext = context;
|
|
230
|
+
const router = getRouter(runtimeContext, getClientBasename(runtimeContext));
|
|
231
|
+
if (null != router) return getTanstackSsrHydrationPromise(router).then(()=>void 0);
|
|
232
|
+
}
|
|
82
233
|
});
|
|
83
234
|
api.wrapRoot((App)=>{
|
|
84
|
-
|
|
85
|
-
const { serverBase = [], supportHtml5History = true, basename = '', routesConfig, createRoutes } = mergedConfig;
|
|
86
|
-
const finalRouteConfig = {
|
|
87
|
-
routes: getGlobalRoutes(),
|
|
88
|
-
globalApp: getGlobalLayoutApp(),
|
|
89
|
-
...routesConfig
|
|
90
|
-
};
|
|
91
|
-
if (!finalRouteConfig.routes && !createRoutes) return App;
|
|
92
|
-
const hooks = api.getHooks();
|
|
93
|
-
let cachedRouteObjects;
|
|
94
|
-
const getRouteObjects = ()=>{
|
|
95
|
-
if (void 0 !== cachedRouteObjects) return cachedRouteObjects;
|
|
96
|
-
const routeObjects = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
|
|
97
|
-
routesConfig: finalRouteConfig
|
|
98
|
-
}) || [];
|
|
99
|
-
const normalizedRouteObjects = createRoutes ? routeObjects : stripSyntheticNotFoundRoute(routeObjects);
|
|
100
|
-
cachedRouteObjects = hooks.modifyRoutes.call(normalizedRouteObjects);
|
|
101
|
-
return cachedRouteObjects;
|
|
102
|
-
};
|
|
103
|
-
const selectBasePath = (pathname)=>{
|
|
104
|
-
const match = serverBase.find((baseUrl)=>isSegmentPrefix(pathname, baseUrl));
|
|
105
|
-
return match || '/';
|
|
106
|
-
};
|
|
107
|
-
let cachedRouteTree = null;
|
|
108
|
-
let cachedRouter = null;
|
|
109
|
-
let cachedRouterBasepath = null;
|
|
235
|
+
if (0 === getRouteObjects().length) return App;
|
|
110
236
|
const RouterWrapper = ()=>{
|
|
111
|
-
const runtimeContext =
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const routeTree = (0, __rspack_external_react.useMemo)(()=>{
|
|
115
|
-
if (cachedRouteTree) return cachedRouteTree;
|
|
116
|
-
const routeObjects = getRouteObjects();
|
|
117
|
-
if (!routeObjects.length) return null;
|
|
118
|
-
cachedRouteTree = createRouteTreeFromRouteObjects(routeObjects, {
|
|
119
|
-
rscPayloadRouter: getGlobalEnableRsc()
|
|
120
|
-
});
|
|
121
|
-
return cachedRouteTree;
|
|
122
|
-
}, []);
|
|
237
|
+
const runtimeContext = useContext(InternalRuntimeContext);
|
|
238
|
+
const _basename = getClientBasename(runtimeContext);
|
|
239
|
+
const routeTree = useMemo(()=>getRouteTree(), []);
|
|
123
240
|
if (!routeTree) return App ? /*#__PURE__*/ jsx(App, {}) : null;
|
|
124
|
-
const router =
|
|
125
|
-
const lifecycleContext = {
|
|
126
|
-
framework: 'tanstack',
|
|
127
|
-
phase: 'client-create',
|
|
128
|
-
routes: getRouteObjects(),
|
|
129
|
-
runtimeContext,
|
|
130
|
-
basename: _basename
|
|
131
|
-
};
|
|
132
|
-
hooks.onBeforeCreateRouter.call(lifecycleContext);
|
|
133
|
-
if (cachedRouter && cachedRouterBasepath === _basename) {
|
|
134
|
-
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
135
|
-
hooks.onAfterCreateRouter.call({
|
|
136
|
-
...lifecycleContext,
|
|
137
|
-
router: cachedRouter,
|
|
138
|
-
runtimeContext
|
|
139
|
-
});
|
|
140
|
-
return cachedRouter;
|
|
141
|
-
}
|
|
142
|
-
const history = supportHtml5History ? createBrowserHistory() : createHashHistory();
|
|
143
|
-
const rewrite = createModernBasepathRewrite(_basename);
|
|
144
|
-
const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
|
|
145
|
-
cachedRouter = createRouter({
|
|
146
|
-
routeTree,
|
|
147
|
-
basepath: '/',
|
|
148
|
-
rewrite,
|
|
149
|
-
history,
|
|
150
|
-
context: {},
|
|
151
|
-
...serializationAdapters ? {
|
|
152
|
-
serializationAdapters
|
|
153
|
-
} : {}
|
|
154
|
-
});
|
|
155
|
-
cachedRouterBasepath = _basename;
|
|
156
|
-
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
157
|
-
hooks.onAfterCreateRouter.call({
|
|
158
|
-
...lifecycleContext,
|
|
159
|
-
router: cachedRouter,
|
|
160
|
-
runtimeContext
|
|
161
|
-
});
|
|
162
|
-
return cachedRouter;
|
|
163
|
-
}, [
|
|
241
|
+
const router = useMemo(()=>getRouter(runtimeContext, _basename), [
|
|
164
242
|
_basename,
|
|
165
243
|
routeTree,
|
|
166
|
-
supportHtml5History,
|
|
167
244
|
runtimeContext
|
|
168
245
|
]);
|
|
246
|
+
if (!router) return App ? /*#__PURE__*/ jsx(App, {}) : null;
|
|
169
247
|
const runtimeState = applyRouterRuntimeState(runtimeContext, {
|
|
170
248
|
framework: 'tanstack',
|
|
171
249
|
basename: _basename,
|
|
@@ -179,30 +257,29 @@ const tanstackRouterPlugin = (userConfig = {})=>{
|
|
|
179
257
|
basename: _basename,
|
|
180
258
|
router
|
|
181
259
|
};
|
|
182
|
-
const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
|
|
183
|
-
|
|
260
|
+
const hasSSRBootstrap = "u" > typeof window && (Boolean(window.$_TSR) || hasTanstackSsrHydrationRecord(router));
|
|
261
|
+
const needsRouterClient = hasSSRBootstrap;
|
|
262
|
+
if (needsRouterClient) hooks.onBeforeHydrateRouter.call({
|
|
184
263
|
...lifecycleContext,
|
|
185
264
|
phase: 'hydrate',
|
|
186
265
|
router,
|
|
187
266
|
runtimeContext: runtimeState
|
|
188
267
|
});
|
|
189
|
-
const RouterContent =
|
|
190
|
-
|
|
191
|
-
children: /*#__PURE__*/ jsx(RouterClient, {
|
|
192
|
-
router: router
|
|
193
|
-
})
|
|
268
|
+
const RouterContent = needsRouterClient ? /*#__PURE__*/ jsx(ModernRouterClient, {
|
|
269
|
+
router: router
|
|
194
270
|
}) : /*#__PURE__*/ jsx(RouterProvider, {
|
|
195
271
|
router: router
|
|
196
272
|
});
|
|
197
|
-
|
|
273
|
+
const HydratableRouterContent = wrapTanstackSsrHydrationBoundary(RouterContent, hasSSRBootstrap);
|
|
274
|
+
if (needsRouterClient) hooks.onAfterHydrateRouter.call({
|
|
198
275
|
...lifecycleContext,
|
|
199
276
|
phase: 'hydrate',
|
|
200
277
|
router,
|
|
201
278
|
runtimeContext: runtimeState
|
|
202
279
|
});
|
|
203
280
|
return App ? /*#__PURE__*/ jsx(App, {
|
|
204
|
-
children:
|
|
205
|
-
}) :
|
|
281
|
+
children: HydratableRouterContent
|
|
282
|
+
}) : HydratableRouterContent;
|
|
206
283
|
};
|
|
207
284
|
return RouterWrapper;
|
|
208
285
|
});
|