@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.9 → 3.5.0-ultramodern.90
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 +157 -0
- package/dist/cjs/cli/index.js +8 -79
- package/dist/cjs/cli/tanstackTypes/canonicalRoutes.js +113 -0
- package/dist/cjs/cli/tanstackTypes/shared.js +123 -0
- package/dist/cjs/cli/tanstackTypes/source.js +255 -0
- package/dist/cjs/cli/tanstackTypes.js +4 -350
- package/dist/cjs/runtime/blockingSubscribe.js +57 -0
- package/dist/cjs/runtime/{pluginCore.js → clientBasepath.js} +12 -19
- package/dist/cjs/runtime/clientHydration.js +118 -0
- package/dist/cjs/runtime/dataMutation.js +11 -176
- package/dist/cjs/runtime/formData.js +116 -0
- package/dist/cjs/runtime/loaderBridge.js +7 -11
- package/dist/cjs/runtime/plugin.js +21 -125
- package/dist/cjs/runtime/plugin.node.js +45 -125
- package/dist/cjs/runtime/pluginShared.js +87 -0
- package/dist/cjs/runtime/prefetchLink.js +15 -2
- package/dist/cjs/runtime/register.js +3 -16
- package/dist/cjs/runtime/routeTree/components.js +102 -0
- package/dist/cjs/runtime/routeTree/construction.js +152 -0
- package/dist/cjs/runtime/routeTree/index.js +47 -0
- package/dist/cjs/runtime/routeTree/loaders.js +158 -0
- package/dist/cjs/runtime/routeTree/paths.js +57 -0
- package/dist/cjs/runtime/routeTree/staticData.js +63 -0
- package/dist/cjs/runtime/routeTree/tanstackRoutes.js +57 -0
- package/dist/cjs/runtime/routeTree/types.js +18 -0
- package/dist/cjs/runtime/routeTree.js +7 -320
- package/dist/cjs/runtime/router.js +15 -2
- package/dist/cjs/runtime/rsc/CompositeComponent.js +18 -13
- package/dist/cjs/runtime/rsc/ReplayableStream.js +0 -4
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +5 -16
- package/dist/cjs/runtime/rsc/client.js +8 -25
- package/dist/cjs/runtime/rsc/flightSerialization.js +132 -0
- package/dist/cjs/runtime/rsc/payloadErrors.js +99 -0
- package/dist/cjs/runtime/rsc/payloadFetch.js +105 -0
- package/dist/cjs/runtime/rsc/payloadRouter.js +21 -142
- package/dist/cjs/runtime/rsc/payloadRoutes.js +94 -0
- package/dist/cjs/runtime/rsc/payloadStorage.js +58 -0
- package/dist/cjs/runtime/rsc/server.js +14 -18
- package/dist/cjs/runtime/rsc/shared.js +68 -0
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +1 -0
- package/dist/cjs/runtime/rsc/treeGetter.js +72 -0
- package/dist/cjs/runtime/shared/isAbsoluteUrl.js +47 -0
- package/dist/cjs/runtime/ssrManagedTags.js +103 -0
- package/dist/cjs/runtime/ssrPreload.js +89 -0
- package/dist/cjs/runtime/ssrTypes.js +18 -0
- package/dist/cjs/runtime/state.js +1 -1
- package/dist/cjs/runtime/submitAction.js +161 -0
- package/dist/cjs/runtime/utils.js +49 -86
- package/dist/esm/cli/artifacts.mjs +103 -0
- package/dist/esm/cli/index.mjs +8 -82
- package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +75 -0
- package/dist/esm/cli/tanstackTypes/shared.mjs +61 -0
- package/dist/esm/cli/tanstackTypes/source.mjs +207 -0
- package/dist/esm/cli/tanstackTypes.mjs +2 -339
- package/dist/esm/runtime/blockingSubscribe.mjs +19 -0
- package/dist/esm/runtime/clientBasepath.mjs +10 -0
- package/dist/esm/runtime/clientHydration.mjs +71 -0
- package/dist/esm/runtime/dataMutation.mjs +2 -167
- package/dist/esm/runtime/formData.mjs +63 -0
- package/dist/esm/runtime/loaderBridge.mjs +5 -9
- package/dist/esm/runtime/plugin.mjs +14 -118
- package/dist/esm/runtime/plugin.node.mjs +41 -121
- package/dist/esm/runtime/pluginShared.mjs +40 -0
- package/dist/esm/runtime/prefetchLink.mjs +18 -5
- package/dist/esm/runtime/register.mjs +1 -14
- package/dist/esm/runtime/routeTree/components.mjs +55 -0
- package/dist/esm/runtime/routeTree/construction.mjs +111 -0
- package/dist/esm/runtime/routeTree/index.mjs +2 -0
- package/dist/esm/runtime/routeTree/loaders.mjs +117 -0
- package/dist/esm/runtime/routeTree/paths.mjs +16 -0
- package/dist/esm/runtime/routeTree/staticData.mjs +22 -0
- package/dist/esm/runtime/routeTree/tanstackRoutes.mjs +13 -0
- package/dist/esm/runtime/routeTree/types.mjs +0 -0
- package/dist/esm/runtime/routeTree.mjs +1 -318
- package/dist/esm/runtime/router.mjs +16 -2
- package/dist/esm/runtime/rsc/CompositeComponent.mjs +18 -13
- package/dist/esm/runtime/rsc/ReplayableStream.mjs +1 -1
- package/dist/esm/runtime/rsc/RscNodeRenderer.mjs +4 -15
- package/dist/esm/runtime/rsc/client.mjs +6 -26
- package/dist/esm/runtime/rsc/flightSerialization.mjs +88 -0
- package/dist/esm/runtime/rsc/payloadErrors.mjs +49 -0
- package/dist/esm/runtime/rsc/payloadFetch.mjs +55 -0
- package/dist/esm/runtime/rsc/payloadRouter.mjs +12 -133
- package/dist/esm/runtime/rsc/payloadRoutes.mjs +50 -0
- package/dist/esm/runtime/rsc/payloadStorage.mjs +14 -0
- package/dist/esm/runtime/rsc/server.mjs +17 -21
- package/dist/esm/runtime/rsc/shared.mjs +21 -0
- package/dist/esm/runtime/rsc/slotUsageSanitizer.mjs +1 -0
- package/dist/esm/runtime/rsc/treeGetter.mjs +34 -0
- package/dist/esm/runtime/shared/isAbsoluteUrl.mjs +9 -0
- package/dist/esm/runtime/ssrManagedTags.mjs +53 -0
- package/dist/esm/runtime/ssrPreload.mjs +51 -0
- package/dist/esm/runtime/ssrTypes.mjs +0 -0
- package/dist/esm/runtime/state.mjs +1 -1
- package/dist/esm/runtime/submitAction.mjs +120 -0
- package/dist/esm/runtime/utils.mjs +47 -75
- package/dist/esm-node/cli/artifacts.mjs +104 -0
- package/dist/esm-node/cli/index.mjs +8 -82
- package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +76 -0
- package/dist/esm-node/cli/tanstackTypes/shared.mjs +62 -0
- package/dist/esm-node/cli/tanstackTypes/source.mjs +208 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +2 -339
- package/dist/esm-node/runtime/blockingSubscribe.mjs +20 -0
- package/dist/esm-node/runtime/clientBasepath.mjs +11 -0
- package/dist/esm-node/runtime/clientHydration.mjs +72 -0
- package/dist/esm-node/runtime/dataMutation.mjs +2 -167
- package/dist/esm-node/runtime/formData.mjs +64 -0
- package/dist/esm-node/runtime/loaderBridge.mjs +5 -9
- package/dist/esm-node/runtime/plugin.mjs +14 -118
- package/dist/esm-node/runtime/plugin.node.mjs +41 -121
- package/dist/esm-node/runtime/pluginShared.mjs +41 -0
- package/dist/esm-node/runtime/prefetchLink.mjs +18 -5
- package/dist/esm-node/runtime/register.mjs +1 -14
- package/dist/esm-node/runtime/routeTree/components.mjs +56 -0
- package/dist/esm-node/runtime/routeTree/construction.mjs +112 -0
- package/dist/esm-node/runtime/routeTree/index.mjs +3 -0
- package/dist/esm-node/runtime/routeTree/loaders.mjs +118 -0
- package/dist/esm-node/runtime/routeTree/paths.mjs +17 -0
- package/dist/esm-node/runtime/routeTree/staticData.mjs +23 -0
- package/dist/esm-node/runtime/routeTree/tanstackRoutes.mjs +14 -0
- package/dist/esm-node/runtime/routeTree/types.mjs +1 -0
- package/dist/esm-node/runtime/routeTree.mjs +1 -318
- package/dist/esm-node/runtime/router.mjs +16 -2
- package/dist/esm-node/runtime/rsc/CompositeComponent.mjs +18 -13
- package/dist/esm-node/runtime/rsc/ReplayableStream.mjs +1 -1
- package/dist/esm-node/runtime/rsc/RscNodeRenderer.mjs +4 -15
- package/dist/esm-node/runtime/rsc/client.mjs +6 -26
- package/dist/esm-node/runtime/rsc/flightSerialization.mjs +89 -0
- package/dist/esm-node/runtime/rsc/payloadErrors.mjs +50 -0
- package/dist/esm-node/runtime/rsc/payloadFetch.mjs +56 -0
- package/dist/esm-node/runtime/rsc/payloadRouter.mjs +12 -133
- package/dist/esm-node/runtime/rsc/payloadRoutes.mjs +51 -0
- package/dist/esm-node/runtime/rsc/payloadStorage.mjs +15 -0
- package/dist/esm-node/runtime/rsc/server.mjs +17 -21
- package/dist/esm-node/runtime/rsc/shared.mjs +22 -0
- package/dist/esm-node/runtime/rsc/slotUsageSanitizer.mjs +1 -0
- package/dist/esm-node/runtime/rsc/treeGetter.mjs +35 -0
- package/dist/esm-node/runtime/shared/isAbsoluteUrl.mjs +10 -0
- package/dist/esm-node/runtime/ssrManagedTags.mjs +54 -0
- package/dist/esm-node/runtime/ssrPreload.mjs +52 -0
- package/dist/esm-node/runtime/ssrTypes.mjs +1 -0
- package/dist/esm-node/runtime/state.mjs +1 -1
- package/dist/esm-node/runtime/submitAction.mjs +121 -0
- package/dist/esm-node/runtime/utils.mjs +47 -75
- package/dist/types/cli/artifacts.d.ts +33 -0
- package/dist/types/cli/index.d.ts +2 -22
- package/dist/types/cli/tanstackTypes/canonicalRoutes.d.ts +22 -0
- package/dist/types/cli/tanstackTypes/shared.d.ts +20 -0
- package/dist/types/cli/tanstackTypes/source.d.ts +12 -0
- package/dist/types/cli/tanstackTypes.d.ts +3 -31
- package/dist/types/runtime/blockingSubscribe.d.ts +1 -0
- package/dist/types/runtime/clientBasepath.d.ts +1 -0
- package/dist/types/runtime/clientHydration.d.ts +10 -0
- package/dist/types/runtime/dataMutation.d.ts +3 -12
- package/dist/types/runtime/formData.d.ts +24 -0
- package/dist/types/runtime/loaderBridge.d.ts +2 -1
- package/dist/types/runtime/plugin.d.ts +1 -1
- package/dist/types/runtime/plugin.node.d.ts +1 -1
- package/dist/types/runtime/pluginShared.d.ts +38 -0
- package/dist/types/runtime/register.d.ts +10 -9
- package/dist/types/runtime/routeTree/components.d.ts +7 -0
- package/dist/types/runtime/routeTree/construction.d.ts +5 -0
- package/dist/types/runtime/routeTree/index.d.ts +2 -0
- package/dist/types/runtime/routeTree/loaders.d.ts +4 -0
- package/dist/types/runtime/routeTree/paths.d.ts +3 -0
- package/dist/types/runtime/routeTree/staticData.d.ts +19 -0
- package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +4 -0
- package/dist/types/runtime/routeTree/types.d.ts +76 -0
- package/dist/types/runtime/routeTree.d.ts +1 -9
- package/dist/types/runtime/router.d.ts +6 -7
- package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -2
- package/dist/types/runtime/rsc/ReplayableStream.d.ts +3 -2
- package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +2 -3
- package/dist/types/runtime/rsc/SlotContext.d.ts +2 -1
- package/dist/types/runtime/rsc/client.d.ts +2 -0
- package/dist/types/runtime/rsc/flightSerialization.d.ts +3 -0
- package/dist/types/runtime/rsc/payloadErrors.d.ts +6 -0
- package/dist/types/runtime/rsc/payloadFetch.d.ts +8 -0
- package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -10
- package/dist/types/runtime/rsc/payloadRoutes.d.ts +40 -0
- package/dist/types/runtime/rsc/payloadStorage.d.ts +5 -0
- package/dist/types/runtime/rsc/shared.d.ts +18 -0
- package/dist/types/runtime/rsc/treeGetter.d.ts +1 -0
- package/dist/types/runtime/shared/isAbsoluteUrl.d.ts +1 -0
- package/dist/types/runtime/ssrManagedTags.d.ts +7 -0
- package/dist/types/runtime/ssrPreload.d.ts +2 -0
- package/dist/types/runtime/ssrTypes.d.ts +44 -0
- package/dist/types/runtime/state.d.ts +1 -1
- package/dist/types/runtime/submitAction.d.ts +14 -0
- package/dist/types/runtime/types.d.ts +4 -10
- package/dist/types/runtime/utils.d.ts +4 -24
- package/package.json +37 -17
- package/rstest.config.mts +23 -0
- package/src/cli/artifacts.ts +255 -0
- package/src/cli/index.ts +7 -185
- package/src/cli/tanstackTypes/canonicalRoutes.ts +157 -0
- package/src/cli/tanstackTypes/shared.ts +113 -0
- package/src/cli/tanstackTypes/source.ts +414 -0
- package/src/cli/tanstackTypes.ts +4 -647
- package/src/runtime/blockingSubscribe.ts +48 -0
- package/src/runtime/clientBasepath.ts +12 -0
- package/src/runtime/clientHydration.ts +149 -0
- package/src/runtime/dataMutation.tsx +9 -306
- package/src/runtime/formData.ts +153 -0
- package/src/runtime/loaderBridge.ts +11 -12
- package/src/runtime/plugin.node.tsx +76 -291
- package/src/runtime/plugin.tsx +21 -257
- package/src/runtime/pluginShared.ts +112 -0
- package/src/runtime/prefetchLink.tsx +78 -15
- package/src/runtime/register.ts +10 -42
- package/src/runtime/routeTree/components.ts +130 -0
- package/src/runtime/routeTree/construction.ts +238 -0
- package/src/runtime/routeTree/index.ts +7 -0
- package/src/runtime/routeTree/loaders.ts +232 -0
- package/src/runtime/routeTree/paths.ts +36 -0
- package/src/runtime/routeTree/staticData.ts +66 -0
- package/src/runtime/routeTree/tanstackRoutes.ts +36 -0
- package/src/runtime/routeTree/types.ts +87 -0
- package/src/runtime/routeTree.ts +5 -750
- package/src/runtime/router.ts +35 -7
- package/src/runtime/rsc/CompositeComponent.tsx +29 -20
- package/src/runtime/rsc/ReplayableStream.ts +2 -2
- package/src/runtime/rsc/RscNodeRenderer.tsx +9 -27
- package/src/runtime/rsc/SlotContext.tsx +1 -1
- package/src/runtime/rsc/client.tsx +12 -40
- package/src/runtime/rsc/flightSerialization.ts +158 -0
- package/src/runtime/rsc/payloadErrors.ts +73 -0
- package/src/runtime/rsc/payloadFetch.ts +92 -0
- package/src/runtime/rsc/payloadRouter.ts +29 -234
- package/src/runtime/rsc/payloadRoutes.ts +122 -0
- package/src/runtime/rsc/payloadStorage.ts +35 -0
- package/src/runtime/rsc/server.tsx +20 -29
- package/src/runtime/rsc/shared.ts +70 -0
- package/src/runtime/rsc/slotUsageSanitizer.ts +4 -0
- package/src/runtime/rsc/treeGetter.tsx +52 -0
- package/src/runtime/shared/isAbsoluteUrl.ts +8 -0
- package/src/runtime/ssrManagedTags.ts +107 -0
- package/src/runtime/ssrPreload.ts +125 -0
- package/src/runtime/ssrTypes.ts +51 -0
- package/src/runtime/state.ts +9 -3
- package/src/runtime/submitAction.ts +201 -0
- package/src/runtime/types.ts +4 -18
- package/src/runtime/utils.tsx +76 -110
- package/src/types/react-server-dom-rspack.d.ts +56 -0
- package/tests/castRatchet.test.ts +85 -0
- package/tests/realm-isolation.test.ts +114 -0
- package/tests/router/cli.test.ts +7 -0
- package/tests/router/clientHydration.test.tsx +61 -0
- package/tests/router/dataMutation.test.tsx +59 -0
- package/tests/router/fixtures/legacyRuntimeRouter.ts +10 -0
- package/tests/router/fixtures/router-gen.golden.txt +71 -0
- package/tests/router/fixtures/router-gen.oxlint.json +5 -0
- package/tests/router/flightSerialization.roundtrip.test.tsx +137 -0
- package/tests/router/generateRouteArtifacts.test.ts +106 -0
- package/tests/router/hooks.test.ts +14 -0
- package/tests/router/loaderBridge.test.ts +21 -0
- package/tests/router/prefetchLink.test.tsx +106 -59
- package/tests/router/prefetchLinkPreload.test.tsx +85 -0
- package/tests/router/register.test.ts +1 -39
- package/tests/router/routeTree.test.ts +51 -11
- package/tests/router/routerCompatibility.test.ts +245 -0
- package/tests/router/rsc.test.tsx +189 -0
- package/tests/router/rscPayloadRouterMatrix.test.ts +197 -0
- package/tests/router/slotUsageSanitizer.test.ts +23 -0
- package/tests/router/ssrPreload.test.ts +30 -0
- package/tests/router/tanstackTypes.test.ts +298 -1
- package/dist/esm/runtime/pluginCore.mjs +0 -14
- package/dist/esm-node/runtime/pluginCore.mjs +0 -15
- package/dist/types/runtime/pluginCore.d.ts +0 -21
- package/src/runtime/pluginCore.ts +0 -48
|
@@ -1,47 +1,25 @@
|
|
|
1
1
|
// @effect-diagnostics asyncFunction:off globalFetch:off processEnv:off strictBooleanExpressions:off
|
|
2
2
|
import type { PayloadRoute, ServerPayload } from '@modern-js/runtime/context';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
parentRoute?: RouterRouteLike;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type RouterMatchLike = {
|
|
28
|
-
error?: unknown;
|
|
29
|
-
id?: unknown;
|
|
30
|
-
loaderData?: unknown;
|
|
31
|
-
params?: unknown;
|
|
32
|
-
pathname?: unknown;
|
|
33
|
-
pathnameBase?: unknown;
|
|
34
|
-
route?: RouterRouteLike;
|
|
35
|
-
routeId?: unknown;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
type TanstackPayloadRouterLike = {
|
|
39
|
-
state?: {
|
|
40
|
-
location?: unknown;
|
|
41
|
-
matches?: unknown;
|
|
42
|
-
statusCode?: unknown;
|
|
43
|
-
};
|
|
44
|
-
};
|
|
3
|
+
import { notFound } from '@tanstack/react-router';
|
|
4
|
+
import { serializeTanstackRscFlightValues } from './flightSerialization';
|
|
5
|
+
import {
|
|
6
|
+
isSerializedNotFound,
|
|
7
|
+
serializePayloadError,
|
|
8
|
+
toRouteErrors,
|
|
9
|
+
toRouteLoaderData,
|
|
10
|
+
} from './payloadErrors';
|
|
11
|
+
import {
|
|
12
|
+
createPayloadFetchKey,
|
|
13
|
+
fetchTanstackRscPayload,
|
|
14
|
+
payloadFetchCache,
|
|
15
|
+
} from './payloadFetch';
|
|
16
|
+
import type {
|
|
17
|
+
RouterMatchLike,
|
|
18
|
+
TanstackPayloadRouterLike,
|
|
19
|
+
} from './payloadRoutes';
|
|
20
|
+
import { toPayloadRoute, toPlainLocation } from './payloadRoutes';
|
|
21
|
+
|
|
22
|
+
export { __setTanstackRscPayloadDecoderForTests } from './payloadFetch';
|
|
45
23
|
|
|
46
24
|
type LoadRouteDataOptions = {
|
|
47
25
|
hasClientLoader?: boolean;
|
|
@@ -50,102 +28,6 @@ type LoadRouteDataOptions = {
|
|
|
50
28
|
routeId?: string;
|
|
51
29
|
};
|
|
52
30
|
|
|
53
|
-
const payloadFetchCache = new Map<string, Promise<ServerPayload>>();
|
|
54
|
-
let payloadDecoder: PayloadDecoder | undefined;
|
|
55
|
-
|
|
56
|
-
function getRouteId(match: RouterMatchLike) {
|
|
57
|
-
const routeId = match.routeId ?? match.route?.id ?? match.id;
|
|
58
|
-
return typeof routeId === 'string' ? routeId : undefined;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function getRouteStaticData(match: RouterMatchLike) {
|
|
62
|
-
return match.route?.options?.staticData || {};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function getRouteParentId(match: RouterMatchLike) {
|
|
66
|
-
const parentId = match.route?.parentRoute?.id;
|
|
67
|
-
return typeof parentId === 'string' ? parentId : undefined;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function toRoutePath(match: RouterMatchLike) {
|
|
71
|
-
const path = match.route?.options?.path;
|
|
72
|
-
return typeof path === 'string' ? path : undefined;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function toPayloadRoute(match: RouterMatchLike): PayloadRoute | undefined {
|
|
76
|
-
const routeId = getRouteId(match);
|
|
77
|
-
if (!routeId) {
|
|
78
|
-
return undefined;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const staticData = getRouteStaticData(match);
|
|
82
|
-
const params =
|
|
83
|
-
match.params && typeof match.params === 'object'
|
|
84
|
-
? (match.params as Record<string, string>)
|
|
85
|
-
: {};
|
|
86
|
-
const pathname = typeof match.pathname === 'string' ? match.pathname : '';
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
handle: staticData.modernRouteHandle,
|
|
90
|
-
hasAction: Boolean(
|
|
91
|
-
staticData.modernRouteHasAction || staticData.modernRouteAction,
|
|
92
|
-
),
|
|
93
|
-
hasErrorBoundary: false,
|
|
94
|
-
hasLoader: Boolean(staticData.modernRouteHasLoader),
|
|
95
|
-
hasClientLoader: Boolean(staticData.modernRouteHasClientLoader),
|
|
96
|
-
id: routeId,
|
|
97
|
-
index: Boolean(match.route?.options?.index) || undefined,
|
|
98
|
-
params,
|
|
99
|
-
parentId: getRouteParentId(match),
|
|
100
|
-
path: toRoutePath(match),
|
|
101
|
-
pathname,
|
|
102
|
-
pathnameBase:
|
|
103
|
-
typeof match.pathnameBase === 'string' ? match.pathnameBase : pathname,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function shouldRedactServerError(status = 500) {
|
|
108
|
-
return (
|
|
109
|
-
status >= 500 &&
|
|
110
|
-
process.env.NODE_ENV !== 'development' &&
|
|
111
|
-
process.env.NODE_ENV !== 'test'
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function serializePayloadError(error: unknown): unknown {
|
|
116
|
-
if (isRouteErrorResponse(error)) {
|
|
117
|
-
if (shouldRedactServerError(error.status)) {
|
|
118
|
-
return {
|
|
119
|
-
status: error.status,
|
|
120
|
-
statusText: 'Internal Server Error',
|
|
121
|
-
data: 'Unexpected Server Error',
|
|
122
|
-
__type: 'RouteErrorResponse',
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return { ...error, __type: 'RouteErrorResponse' };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (error instanceof Error) {
|
|
130
|
-
if (shouldRedactServerError()) {
|
|
131
|
-
return {
|
|
132
|
-
message: 'Unexpected Server Error',
|
|
133
|
-
stack: undefined,
|
|
134
|
-
__type: 'Error',
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
message: error.message,
|
|
140
|
-
stack: error.stack,
|
|
141
|
-
__type: 'Error',
|
|
142
|
-
...(error.name !== 'Error' ? { __subType: error.name } : {}),
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return error;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
31
|
export function createTanstackRscServerPayload(
|
|
150
32
|
router: TanstackPayloadRouterLike,
|
|
151
33
|
options: {
|
|
@@ -172,7 +54,9 @@ export function createTanstackRscServerPayload(
|
|
|
172
54
|
typeof match.loaderData !== 'undefined' &&
|
|
173
55
|
!(options.omitClientLoaderData && payloadRoute.hasClientLoader)
|
|
174
56
|
) {
|
|
175
|
-
loaderData[payloadRoute.id] =
|
|
57
|
+
loaderData[payloadRoute.id] = serializeTanstackRscFlightValues(
|
|
58
|
+
match.loaderData,
|
|
59
|
+
);
|
|
176
60
|
}
|
|
177
61
|
|
|
178
62
|
if (typeof match.error !== 'undefined') {
|
|
@@ -185,7 +69,7 @@ export function createTanstackRscServerPayload(
|
|
|
185
69
|
actionData: null,
|
|
186
70
|
errors: Object.keys(errors).length > 0 ? errors : null,
|
|
187
71
|
loaderData,
|
|
188
|
-
location: router.state?.location
|
|
72
|
+
location: toPlainLocation(router.state?.location),
|
|
189
73
|
routes,
|
|
190
74
|
};
|
|
191
75
|
}
|
|
@@ -199,7 +83,11 @@ export function handleTanstackRscRedirect(
|
|
|
199
83
|
let redirectUrl = headers.get('Location') || '/';
|
|
200
84
|
|
|
201
85
|
if (basename !== '/') {
|
|
202
|
-
redirectUrl
|
|
86
|
+
if (redirectUrl === basename) {
|
|
87
|
+
redirectUrl = '/';
|
|
88
|
+
} else if (redirectUrl.startsWith(`${basename}/`)) {
|
|
89
|
+
redirectUrl = redirectUrl.slice(basename.length);
|
|
90
|
+
}
|
|
203
91
|
}
|
|
204
92
|
|
|
205
93
|
newHeaders.set('X-Modernjs-Redirect', redirectUrl);
|
|
@@ -216,72 +104,6 @@ export function isTanstackRscPayloadNavigationEnabled() {
|
|
|
216
104
|
return typeof window !== 'undefined';
|
|
217
105
|
}
|
|
218
106
|
|
|
219
|
-
async function decodePayload(stream: ReadableStream<Uint8Array>) {
|
|
220
|
-
if (payloadDecoder) {
|
|
221
|
-
return payloadDecoder(stream);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const runtime = await import('@modern-js/runtime/rsc/client');
|
|
225
|
-
return runtime.createFromReadableStream(stream);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function isServerPayload(value: unknown): value is ServerPayload {
|
|
229
|
-
return (
|
|
230
|
-
Boolean(value) &&
|
|
231
|
-
typeof value === 'object' &&
|
|
232
|
-
(value as ServerPayload).type === 'render' &&
|
|
233
|
-
Array.isArray((value as ServerPayload).routes)
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function createPayloadFetchKey(request: Request) {
|
|
238
|
-
return request.url;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function isAbsoluteUrl(value: string) {
|
|
242
|
-
try {
|
|
243
|
-
void new URL(value);
|
|
244
|
-
return true;
|
|
245
|
-
} catch {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async function fetchTanstackRscPayload(request: Request) {
|
|
251
|
-
const headers = new Headers(request.headers);
|
|
252
|
-
headers.set('x-rsc-tree', 'true');
|
|
253
|
-
|
|
254
|
-
const response = await fetch(request.url, {
|
|
255
|
-
credentials: 'same-origin',
|
|
256
|
-
headers,
|
|
257
|
-
method: 'GET',
|
|
258
|
-
signal: request.signal,
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
const redirectLocation = response.headers.get('X-Modernjs-Redirect');
|
|
262
|
-
if (redirectLocation) {
|
|
263
|
-
if (isAbsoluteUrl(redirectLocation)) {
|
|
264
|
-
throw redirect({ href: redirectLocation });
|
|
265
|
-
}
|
|
266
|
-
throw redirect({ to: redirectLocation || '/' });
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (response.status === 404 && !response.body) {
|
|
270
|
-
throw notFound();
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (!response.body) {
|
|
274
|
-
throw new Error('TanStack RSC payload response body is null.');
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const payload = await decodePayload(response.body);
|
|
278
|
-
if (!isServerPayload(payload)) {
|
|
279
|
-
throw new Error('Unexpected TanStack RSC payload type.');
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return payload;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
107
|
export function loadTanstackRscPayload(request: Request) {
|
|
286
108
|
const key = createPayloadFetchKey(request);
|
|
287
109
|
let payloadPromise = payloadFetchCache.get(key);
|
|
@@ -294,26 +116,6 @@ export function loadTanstackRscPayload(request: Request) {
|
|
|
294
116
|
return payloadPromise;
|
|
295
117
|
}
|
|
296
118
|
|
|
297
|
-
function isSerializedNotFound(value: unknown) {
|
|
298
|
-
return (
|
|
299
|
-
Boolean(value) &&
|
|
300
|
-
typeof value === 'object' &&
|
|
301
|
-
(value as { isNotFound?: unknown }).isNotFound === true
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
function toRouteErrors(payload: ServerPayload) {
|
|
306
|
-
return payload.errors && typeof payload.errors === 'object'
|
|
307
|
-
? (payload.errors as Record<string, unknown>)
|
|
308
|
-
: {};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function toRouteLoaderData(payload: ServerPayload) {
|
|
312
|
-
return payload.loaderData && typeof payload.loaderData === 'object'
|
|
313
|
-
? (payload.loaderData as Record<string, unknown>)
|
|
314
|
-
: {};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
119
|
export async function loadTanstackRscRouteData({
|
|
318
120
|
hasClientLoader,
|
|
319
121
|
loadClientData,
|
|
@@ -353,10 +155,3 @@ export async function loadTanstackRscRouteData({
|
|
|
353
155
|
|
|
354
156
|
return undefined;
|
|
355
157
|
}
|
|
356
|
-
|
|
357
|
-
export function __setTanstackRscPayloadDecoderForTests(
|
|
358
|
-
decoder?: PayloadDecoder,
|
|
359
|
-
) {
|
|
360
|
-
payloadDecoder = decoder;
|
|
361
|
-
payloadFetchCache.clear();
|
|
362
|
-
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// @effect-diagnostics asyncFunction:off globalFetch:off processEnv:off strictBooleanExpressions:off
|
|
2
|
+
import type { PayloadRoute, ServerPayload } from '@modern-js/runtime/context';
|
|
3
|
+
|
|
4
|
+
type RouterStaticData = {
|
|
5
|
+
modernRouteAction?: unknown;
|
|
6
|
+
modernRouteHandle?: unknown;
|
|
7
|
+
modernRouteHasAction?: unknown;
|
|
8
|
+
modernRouteHasClientLoader?: unknown;
|
|
9
|
+
modernRouteHasLoader?: unknown;
|
|
10
|
+
modernRouteId?: unknown;
|
|
11
|
+
modernRouteIsClientComponent?: unknown;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type RouterRouteLike = {
|
|
15
|
+
id?: unknown;
|
|
16
|
+
options?: {
|
|
17
|
+
index?: unknown;
|
|
18
|
+
path?: unknown;
|
|
19
|
+
staticData?: RouterStaticData;
|
|
20
|
+
};
|
|
21
|
+
parentRoute?: RouterRouteLike;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type RouterMatchLike = {
|
|
25
|
+
error?: unknown;
|
|
26
|
+
id?: unknown;
|
|
27
|
+
loaderData?: unknown;
|
|
28
|
+
params?: unknown;
|
|
29
|
+
pathname?: unknown;
|
|
30
|
+
pathnameBase?: unknown;
|
|
31
|
+
route?: RouterRouteLike;
|
|
32
|
+
routeId?: unknown;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type TanstackPayloadRouterLike = {
|
|
36
|
+
state?: {
|
|
37
|
+
location?: unknown;
|
|
38
|
+
matches?: unknown;
|
|
39
|
+
statusCode?: unknown;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function toPlainRecord(value: unknown): Record<string, unknown> {
|
|
44
|
+
if (!value || typeof value !== 'object') {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return Object.fromEntries(Object.entries(value as Record<string, unknown>));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function toPlainLocation(location: unknown): ServerPayload['location'] {
|
|
52
|
+
if (!location || typeof location !== 'object') {
|
|
53
|
+
return location as ServerPayload['location'];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const plainLocation = toPlainRecord(location);
|
|
57
|
+
|
|
58
|
+
for (const key of ['search', 'state']) {
|
|
59
|
+
if (
|
|
60
|
+
plainLocation[key] &&
|
|
61
|
+
typeof plainLocation[key] === 'object' &&
|
|
62
|
+
!Array.isArray(plainLocation[key])
|
|
63
|
+
) {
|
|
64
|
+
plainLocation[key] = toPlainRecord(plainLocation[key]);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return plainLocation as unknown as ServerPayload['location'];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function getRouteId(match: RouterMatchLike) {
|
|
72
|
+
const routeId = match.routeId ?? match.route?.id ?? match.id;
|
|
73
|
+
return typeof routeId === 'string' ? routeId : undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getRouteStaticData(match: RouterMatchLike) {
|
|
77
|
+
return match.route?.options?.staticData || {};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getRouteParentId(match: RouterMatchLike) {
|
|
81
|
+
const parentId = match.route?.parentRoute?.id;
|
|
82
|
+
return typeof parentId === 'string' ? parentId : undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function toRoutePath(match: RouterMatchLike) {
|
|
86
|
+
const path = match.route?.options?.path;
|
|
87
|
+
return typeof path === 'string' ? path : undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function toPayloadRoute(
|
|
91
|
+
match: RouterMatchLike,
|
|
92
|
+
): PayloadRoute | undefined {
|
|
93
|
+
const routeId = getRouteId(match);
|
|
94
|
+
if (!routeId) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const staticData = getRouteStaticData(match);
|
|
99
|
+
const params =
|
|
100
|
+
match.params && typeof match.params === 'object'
|
|
101
|
+
? (toPlainRecord(match.params) as Record<string, string>)
|
|
102
|
+
: {};
|
|
103
|
+
const pathname = typeof match.pathname === 'string' ? match.pathname : '';
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
handle: staticData.modernRouteHandle,
|
|
107
|
+
hasAction: Boolean(
|
|
108
|
+
staticData.modernRouteHasAction || staticData.modernRouteAction,
|
|
109
|
+
),
|
|
110
|
+
hasErrorBoundary: false,
|
|
111
|
+
hasLoader: Boolean(staticData.modernRouteHasLoader),
|
|
112
|
+
hasClientLoader: Boolean(staticData.modernRouteHasClientLoader),
|
|
113
|
+
id: routeId,
|
|
114
|
+
index: Boolean(match.route?.options?.index) || undefined,
|
|
115
|
+
params,
|
|
116
|
+
parentId: getRouteParentId(match),
|
|
117
|
+
path: toRoutePath(match),
|
|
118
|
+
pathname,
|
|
119
|
+
pathnameBase:
|
|
120
|
+
typeof match.pathnameBase === 'string' ? match.pathnameBase : pathname,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @effect-diagnostics strictBooleanExpressions:off
|
|
2
|
+
|
|
3
|
+
import type { ServerPayload } from '@modern-js/runtime/context';
|
|
4
|
+
import { storage } from '@modern-js/runtime-utils/node';
|
|
5
|
+
import type { TanstackRouterWithServerSsr } from '../ssrTypes';
|
|
6
|
+
|
|
7
|
+
type TanstackRscStorageContext = {
|
|
8
|
+
serverPayload?: ServerPayload;
|
|
9
|
+
tanstackRscRouter?: TanstackRouterWithServerSsr;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const setTanstackRscServerPayload = (payload: ServerPayload) => {
|
|
13
|
+
const storageContext = storage.useContext?.() as
|
|
14
|
+
| TanstackRscStorageContext
|
|
15
|
+
| undefined;
|
|
16
|
+
if (storageContext) {
|
|
17
|
+
storageContext.serverPayload = payload;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const setTanstackRscRouter = (router: TanstackRouterWithServerSsr) => {
|
|
22
|
+
const storageContext = storage.useContext?.() as
|
|
23
|
+
| TanstackRscStorageContext
|
|
24
|
+
| undefined;
|
|
25
|
+
if (storageContext) {
|
|
26
|
+
storageContext.tanstackRscRouter = router;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const getTanstackRscRouter = () => {
|
|
31
|
+
const storageContext = storage.useContext?.() as
|
|
32
|
+
| TanstackRscStorageContext
|
|
33
|
+
| undefined;
|
|
34
|
+
return storageContext?.tanstackRscRouter;
|
|
35
|
+
};
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
// @effect-diagnostics asyncFunction:off processEnv:off strictBooleanExpressions:off
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '@modern-js/runtime/rsc/server';
|
|
6
|
-
import { createSerializationAdapter } from '@tanstack/react-router';
|
|
7
|
-
import { RawStream } from '@tanstack/router-core';
|
|
8
|
-
import React, { createElement, use } from 'react';
|
|
2
|
+
import { renderRsc } from '@modern-js/runtime/rsc/server';
|
|
3
|
+
import { createSerializationAdapter, RawStream } from '@tanstack/router-core';
|
|
4
|
+
import React, { createElement } from 'react';
|
|
9
5
|
import { ClientSlot } from './ClientSlot';
|
|
10
|
-
import { createRscProxy } from './createRscProxy';
|
|
11
6
|
import { ReplayableStream } from './ReplayableStream';
|
|
12
7
|
import { sanitizeSlotArgs } from './slotUsageSanitizer';
|
|
13
8
|
import {
|
|
@@ -15,6 +10,7 @@ import {
|
|
|
15
10
|
type AnyRenderableServerComponent,
|
|
16
11
|
isRenderableServerComponent,
|
|
17
12
|
isServerComponent,
|
|
13
|
+
RENDERABLE_RSC,
|
|
18
14
|
RSC_SLOT_USAGES_STREAM,
|
|
19
15
|
type RscSlotUsageEvent,
|
|
20
16
|
SERVER_COMPONENT_STREAM,
|
|
@@ -34,25 +30,6 @@ type SlotEmitter<T> = {
|
|
|
34
30
|
stream: ReadableStream<T>;
|
|
35
31
|
};
|
|
36
32
|
|
|
37
|
-
function createTreeGetter(stream: ServerComponentStream) {
|
|
38
|
-
let ready = false;
|
|
39
|
-
let tree: unknown;
|
|
40
|
-
const treePromise = Promise.resolve(
|
|
41
|
-
createFromReadableStream(stream.createReplayStream()),
|
|
42
|
-
).then(value => {
|
|
43
|
-
tree = value;
|
|
44
|
-
ready = true;
|
|
45
|
-
return value;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
return () => {
|
|
49
|
-
if (ready) {
|
|
50
|
-
return tree;
|
|
51
|
-
}
|
|
52
|
-
return use(treePromise);
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
33
|
function createSlotProxy(options?: {
|
|
57
34
|
onSlotCall?: (slot: string, args: unknown[]) => void;
|
|
58
35
|
}) {
|
|
@@ -79,6 +56,20 @@ function createSlotProxy(options?: {
|
|
|
79
56
|
});
|
|
80
57
|
}
|
|
81
58
|
|
|
59
|
+
function createServerRscValue(options: {
|
|
60
|
+
renderable: boolean;
|
|
61
|
+
slotUsagesStream?: ReadableStream<RscSlotUsageEvent>;
|
|
62
|
+
stream: ServerComponentStream;
|
|
63
|
+
}) {
|
|
64
|
+
return {
|
|
65
|
+
[SERVER_COMPONENT_STREAM]: options.stream,
|
|
66
|
+
...(options.renderable ? { [RENDERABLE_RSC]: true } : {}),
|
|
67
|
+
...(options.slotUsagesStream
|
|
68
|
+
? { [RSC_SLOT_USAGES_STREAM]: options.slotUsagesStream }
|
|
69
|
+
: {}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
82
73
|
function toReplayableFlightStream(
|
|
83
74
|
node: React.ReactElement,
|
|
84
75
|
handlers?: {
|
|
@@ -103,7 +94,7 @@ export async function renderServerComponent<TNode extends React.ReactNode>(
|
|
|
103
94
|
createReplayStream: () => stream.createReplayStream(),
|
|
104
95
|
};
|
|
105
96
|
|
|
106
|
-
return
|
|
97
|
+
return createServerRscValue({
|
|
107
98
|
renderable: true,
|
|
108
99
|
stream: streamWrapper,
|
|
109
100
|
}) as TNode & AnyRenderableServerComponent<TNode>;
|
|
@@ -150,7 +141,7 @@ export async function createCompositeComponent<
|
|
|
150
141
|
createReplayStream: () => flightStream.createReplayStream(),
|
|
151
142
|
};
|
|
152
143
|
|
|
153
|
-
return
|
|
144
|
+
return createServerRscValue({
|
|
154
145
|
renderable: false,
|
|
155
146
|
slotUsagesStream: slotUsagesEmitter?.stream,
|
|
156
147
|
stream: streamWrapper,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
type AnyCompositeComponent,
|
|
4
|
+
type AnyRenderableServerComponent,
|
|
5
|
+
RSC_PROXY_GET_TREE,
|
|
6
|
+
RSC_PROXY_PATH,
|
|
7
|
+
type RscSlotUsageEvent,
|
|
8
|
+
} from './symbols';
|
|
9
|
+
|
|
10
|
+
export const TANSTACK_RSC_FLIGHT_VALUE = '__modernTanstackRsc';
|
|
11
|
+
|
|
12
|
+
export type SerializedTanstackRscFlightValue = {
|
|
13
|
+
[TANSTACK_RSC_FLIGHT_VALUE]: true;
|
|
14
|
+
kind: 'renderable' | 'composite';
|
|
15
|
+
slotUsagesStream?: ReadableStream<RscSlotUsageEvent>;
|
|
16
|
+
stream: ReadableStream<Uint8Array>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function isSerializedTanstackRscFlightValue(
|
|
20
|
+
value: unknown,
|
|
21
|
+
): value is SerializedTanstackRscFlightValue {
|
|
22
|
+
return (
|
|
23
|
+
Boolean(value) &&
|
|
24
|
+
typeof value === 'object' &&
|
|
25
|
+
(value as { [TANSTACK_RSC_FLIGHT_VALUE]?: unknown })[
|
|
26
|
+
TANSTACK_RSC_FLIGHT_VALUE
|
|
27
|
+
] === true &&
|
|
28
|
+
((value as { kind?: unknown }).kind === 'renderable' ||
|
|
29
|
+
(value as { kind?: unknown }).kind === 'composite') &&
|
|
30
|
+
(value as { stream?: unknown }).stream instanceof ReadableStream
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function EmptyFallback() {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function selectTreePath(tree: unknown, path: string[]) {
|
|
39
|
+
let current = tree;
|
|
40
|
+
for (const key of path) {
|
|
41
|
+
if (current === null || typeof current !== 'object') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
current = (current as Record<string, unknown>)[key];
|
|
45
|
+
}
|
|
46
|
+
return current as React.ReactNode;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type RenderSelectedTreeSource =
|
|
50
|
+
| AnyRenderableServerComponent
|
|
51
|
+
| AnyCompositeComponent;
|
|
52
|
+
|
|
53
|
+
type RenderSelectedTreeOptions = {
|
|
54
|
+
getTree?: (() => unknown) | undefined;
|
|
55
|
+
missingTreeError: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export function renderSelectedTree(
|
|
59
|
+
src: RenderSelectedTreeSource,
|
|
60
|
+
{
|
|
61
|
+
getTree = src[RSC_PROXY_GET_TREE],
|
|
62
|
+
missingTreeError,
|
|
63
|
+
}: RenderSelectedTreeOptions,
|
|
64
|
+
) {
|
|
65
|
+
if (!getTree) {
|
|
66
|
+
throw new Error(missingTreeError);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return selectTreePath(getTree(), src[RSC_PROXY_PATH] || []);
|
|
70
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { use } from 'react';
|
|
4
|
+
|
|
5
|
+
type ModernRscClientRuntime = typeof import('@modern-js/runtime/rsc/client');
|
|
6
|
+
type ServerRscClientRuntime =
|
|
7
|
+
typeof import('react-server-dom-rspack/client.edge');
|
|
8
|
+
|
|
9
|
+
let modernRscClientRuntimePromise: Promise<ModernRscClientRuntime> | undefined;
|
|
10
|
+
|
|
11
|
+
function loadModernRscClientRuntime() {
|
|
12
|
+
modernRscClientRuntimePromise ??= import(
|
|
13
|
+
'@modern-js/runtime/rsc/client'
|
|
14
|
+
).then(runtime => {
|
|
15
|
+
runtime.setServerCallback(runtime.callServer);
|
|
16
|
+
return runtime;
|
|
17
|
+
});
|
|
18
|
+
return modernRscClientRuntimePromise;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function createFromFlightStream(stream: ReadableStream<Uint8Array>) {
|
|
22
|
+
if (typeof window === 'undefined') {
|
|
23
|
+
const runtime: ServerRscClientRuntime = await import(
|
|
24
|
+
'react-server-dom-rspack/client.edge'
|
|
25
|
+
);
|
|
26
|
+
return runtime.createFromReadableStream(stream);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const runtime = await loadModernRscClientRuntime();
|
|
30
|
+
return runtime.createFromReadableStream(stream, {
|
|
31
|
+
callServer: runtime.callServer,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createTreeGetterFromFlightStream(
|
|
36
|
+
stream: ReadableStream<Uint8Array>,
|
|
37
|
+
) {
|
|
38
|
+
let ready = false;
|
|
39
|
+
let tree: unknown;
|
|
40
|
+
const treePromise = createFromFlightStream(stream).then(value => {
|
|
41
|
+
tree = value;
|
|
42
|
+
ready = true;
|
|
43
|
+
return value;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return () => {
|
|
47
|
+
if (ready) {
|
|
48
|
+
return tree;
|
|
49
|
+
}
|
|
50
|
+
return use(treePromise);
|
|
51
|
+
};
|
|
52
|
+
}
|