@bleedingdev/modern-js-runtime 3.2.0-ultramodern.98 → 3.4.0-ultramodern.0
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/boundary-debugger/index.js +19 -11
- package/dist/cjs/cache/index.js +9 -5
- package/dist/cjs/cli/alias.js +9 -5
- package/dist/cjs/cli/code.js +9 -5
- package/dist/cjs/cli/constants.js +20 -16
- package/dist/cjs/cli/entry.js +9 -5
- package/dist/cjs/cli/index.js +20 -5
- package/dist/cjs/cli/ssr/index.js +9 -5
- package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +9 -5
- package/dist/cjs/cli/ssr/mode.js +12 -8
- package/dist/cjs/cli/template.js +9 -5
- package/dist/cjs/cli/template.server.js +9 -5
- package/dist/cjs/common.js +14 -10
- package/dist/cjs/core/browser/hydrate.js +9 -5
- package/dist/cjs/core/browser/index.js +9 -5
- package/dist/cjs/core/browser/withCallback.js +9 -5
- package/dist/cjs/core/compat/hooks.js +14 -10
- package/dist/cjs/core/compat/index.js +9 -5
- package/dist/cjs/core/compat/requestContext.js +13 -9
- package/dist/cjs/core/config.js +12 -8
- package/dist/cjs/core/constants.js +15 -10
- package/dist/cjs/core/context/extensions.js +69 -0
- package/dist/cjs/core/context/helmetContext.js +54 -0
- package/dist/cjs/core/context/index.js +74 -5
- package/dist/cjs/core/context/monitors/default.js +12 -8
- package/dist/cjs/core/context/monitors/index.js +9 -5
- package/dist/cjs/core/context/monitors/index.server.js +9 -5
- package/dist/cjs/core/context/request/index.js +12 -8
- package/dist/cjs/core/context/request/index.server.js +9 -5
- package/dist/cjs/core/context/response/index.js +15 -11
- package/dist/cjs/core/context/response/index.server.js +9 -5
- package/dist/cjs/core/context/runtime.js +9 -5
- package/dist/cjs/core/context/serverPayload/index.js +13 -9
- package/dist/cjs/core/context/serverPayload/index.server.js +9 -5
- package/dist/cjs/core/index.js +9 -5
- package/dist/cjs/core/plugin/index.js +9 -5
- package/dist/cjs/core/react/index.js +9 -5
- package/dist/cjs/core/react/wrapper.js +15 -9
- package/dist/cjs/core/server/constants.js +15 -11
- package/dist/cjs/core/server/federatedCss.js +11 -7
- package/dist/cjs/core/server/helmet.js +11 -6
- package/dist/cjs/core/server/index.js +9 -5
- package/dist/cjs/core/server/react/index.js +9 -5
- package/dist/cjs/core/server/react/no-ssr-cache/index.js +9 -5
- package/dist/cjs/core/server/react/nossr/index.js +9 -5
- package/dist/cjs/core/server/requestHandler.js +51 -34
- package/dist/cjs/core/server/routerCleanup.js +110 -0
- package/dist/cjs/core/server/scriptOrder.js +84 -9
- package/dist/cjs/core/server/server.js +9 -5
- package/dist/cjs/core/server/shared.js +12 -8
- package/dist/cjs/core/server/stream/afterTemplate.js +15 -23
- package/dist/cjs/core/server/stream/beforeTemplate.js +11 -7
- package/dist/cjs/core/server/stream/beforeTemplate.worker.js +10 -6
- package/dist/cjs/core/server/stream/createReadableStream.js +16 -10
- package/dist/cjs/core/server/stream/createReadableStream.worker.js +15 -7
- package/dist/cjs/core/server/stream/deferredScript.js +13 -6
- package/dist/cjs/core/server/stream/index.js +9 -5
- package/dist/cjs/core/server/stream/shared.js +9 -5
- package/dist/cjs/core/server/stream/template.js +9 -5
- package/dist/cjs/core/server/string/index.js +10 -12
- package/dist/cjs/core/server/string/loadable.js +24 -54
- package/dist/cjs/core/server/string/ssrData.js +10 -6
- package/dist/cjs/core/server/tracer.js +13 -9
- package/dist/cjs/core/server/utils.js +63 -13
- package/dist/cjs/document/Body.js +9 -5
- package/dist/cjs/document/Comment.js +9 -5
- package/dist/cjs/document/DocumentContext.js +9 -5
- package/dist/cjs/document/DocumentStructureContext.js +9 -5
- package/dist/cjs/document/Head.js +9 -5
- package/dist/cjs/document/Html.js +9 -5
- package/dist/cjs/document/Links.js +9 -5
- package/dist/cjs/document/Root.js +9 -5
- package/dist/cjs/document/Script.js +9 -5
- package/dist/cjs/document/Scripts.js +9 -5
- package/dist/cjs/document/Style.js +9 -5
- package/dist/cjs/document/Title.js +9 -5
- package/dist/cjs/document/cli/index.js +14 -11
- package/dist/cjs/document/constants.js +9 -5
- package/dist/cjs/document/index.js +9 -5
- package/dist/cjs/exports/config-routes.js +12 -8
- package/dist/cjs/exports/head.js +153 -83
- package/dist/cjs/exports/loadable.js +27 -18
- package/dist/cjs/exports/tanstack-router.js +50 -58
- package/dist/cjs/index.js +9 -5
- package/dist/cjs/internal.js +9 -5
- package/dist/cjs/module-federation/index.js +178 -0
- package/dist/cjs/react-server.js +9 -5
- package/dist/cjs/router/cli/code/getClientRoutes/getRoutes.js +9 -5
- package/dist/cjs/router/cli/code/getClientRoutes/index.js +9 -5
- package/dist/cjs/router/cli/code/getClientRoutes/utils.js +9 -5
- package/dist/cjs/router/cli/code/index.js +16 -52
- package/dist/cjs/router/cli/code/inspect.js +9 -5
- package/dist/cjs/router/cli/code/makeLegalIdentifier.js +12 -8
- package/dist/cjs/router/cli/code/nestedRoutes.js +9 -5
- package/dist/cjs/router/cli/code/templates.js +10 -19
- package/dist/cjs/router/cli/code/utils.js +9 -5
- package/dist/cjs/router/cli/config-routes/converter.js +9 -5
- package/dist/cjs/router/cli/config-routes/parseRouteConfig.js +9 -5
- package/dist/cjs/router/cli/constants.js +23 -19
- package/dist/cjs/router/cli/entry.js +9 -5
- package/dist/cjs/router/cli/handler.js +10 -6
- package/dist/cjs/router/cli/index.js +11 -29
- package/dist/cjs/router/index.js +9 -5
- package/dist/cjs/router/internal.js +12 -8
- package/dist/cjs/router/runtime/CSSLinks.js +9 -5
- package/dist/cjs/router/runtime/DefaultNotFound.js +9 -5
- package/dist/cjs/router/runtime/DeferredDataScripts.js +12 -8
- package/dist/cjs/router/runtime/DeferredDataScripts.node.js +25 -9
- package/dist/cjs/router/runtime/PrefetchLink.js +161 -26
- package/dist/cjs/router/runtime/constants.js +9 -5
- package/dist/cjs/router/runtime/hooks.js +9 -5
- package/dist/cjs/router/runtime/index.js +15 -10
- package/dist/cjs/router/runtime/internal.js +29 -18
- package/dist/cjs/router/runtime/lifecycle.js +38 -19
- package/dist/cjs/router/runtime/plugin.js +11 -14
- package/dist/cjs/router/runtime/plugin.node.js +11 -12
- package/dist/cjs/router/runtime/provider.js +107 -0
- package/dist/cjs/router/runtime/routerHelper.js +9 -5
- package/dist/cjs/router/runtime/rsc-router.js +19 -9
- package/dist/cjs/router/runtime/rsc.js +9 -5
- package/dist/cjs/router/runtime/server.js +9 -5
- package/dist/cjs/router/runtime/utils.js +44 -15
- package/dist/cjs/router/runtime/withRouter.js +9 -5
- package/dist/cjs/rsc/client.js +12 -8
- package/dist/cjs/rsc/server.js +9 -5
- package/dist/cjs/rsc/server.worker.js +9 -5
- package/dist/esm/boundary-debugger/index.mjs +10 -6
- package/dist/esm/cli/index.mjs +4 -2
- package/dist/esm/core/context/extensions.mjs +28 -0
- package/dist/esm/core/context/helmetContext.mjs +13 -0
- package/dist/esm/core/context/index.mjs +5 -0
- package/dist/esm/core/react/wrapper.mjs +6 -4
- package/dist/esm/core/server/federatedCss.mjs +2 -2
- package/dist/esm/core/server/helmet.mjs +2 -1
- package/dist/esm/core/server/requestHandler.mjs +43 -30
- package/dist/esm/core/server/routerCleanup.mjs +66 -0
- package/dist/esm/core/server/scriptOrder.mjs +62 -3
- package/dist/esm/core/server/stream/afterTemplate.mjs +8 -20
- package/dist/esm/core/server/stream/beforeTemplate.mjs +3 -3
- package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +1 -1
- package/dist/esm/core/server/stream/createReadableStream.mjs +7 -5
- package/dist/esm/core/server/stream/createReadableStream.worker.mjs +6 -2
- package/dist/esm/core/server/stream/deferredScript.mjs +4 -1
- package/dist/esm/core/server/string/index.mjs +3 -9
- package/dist/esm/core/server/string/loadable.mjs +14 -48
- package/dist/esm/core/server/string/ssrData.mjs +2 -2
- package/dist/esm/core/server/utils.mjs +52 -9
- package/dist/esm/document/cli/index.mjs +5 -6
- package/dist/esm/exports/head.mjs +144 -78
- package/dist/esm/exports/loadable.mjs +12 -6
- package/dist/esm/exports/tanstack-router.mjs +30 -3
- package/dist/esm/module-federation/index.mjs +109 -0
- package/dist/esm/router/cli/code/index.mjs +8 -48
- package/dist/esm/router/cli/code/templates.mjs +1 -14
- package/dist/esm/router/cli/handler.mjs +1 -1
- package/dist/esm/router/cli/index.mjs +3 -25
- package/dist/esm/router/runtime/DeferredDataScripts.node.mjs +16 -4
- package/dist/esm/router/runtime/PrefetchLink.mjs +152 -21
- package/dist/esm/router/runtime/internal.mjs +16 -15
- package/dist/esm/router/runtime/lifecycle.mjs +22 -13
- package/dist/esm/router/runtime/plugin.mjs +4 -11
- package/dist/esm/router/runtime/plugin.node.mjs +4 -9
- package/dist/esm/router/runtime/provider.mjs +57 -0
- package/dist/esm/router/runtime/rsc-router.mjs +10 -4
- package/dist/esm/router/runtime/utils.mjs +35 -10
- package/dist/esm-node/boundary-debugger/index.mjs +10 -6
- package/dist/esm-node/cli/index.mjs +4 -2
- package/dist/esm-node/core/context/extensions.mjs +29 -0
- package/dist/esm-node/core/context/helmetContext.mjs +14 -0
- package/dist/esm-node/core/context/index.mjs +5 -0
- package/dist/esm-node/core/react/wrapper.mjs +6 -4
- package/dist/esm-node/core/server/federatedCss.mjs +2 -2
- package/dist/esm-node/core/server/helmet.mjs +2 -1
- package/dist/esm-node/core/server/requestHandler.mjs +43 -30
- package/dist/esm-node/core/server/routerCleanup.mjs +67 -0
- package/dist/esm-node/core/server/scriptOrder.mjs +62 -3
- package/dist/esm-node/core/server/stream/afterTemplate.mjs +8 -20
- package/dist/esm-node/core/server/stream/beforeTemplate.mjs +3 -3
- package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +1 -1
- package/dist/esm-node/core/server/stream/createReadableStream.mjs +7 -5
- package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +6 -2
- package/dist/esm-node/core/server/stream/deferredScript.mjs +4 -1
- package/dist/esm-node/core/server/string/index.mjs +3 -9
- package/dist/esm-node/core/server/string/loadable.mjs +14 -48
- package/dist/esm-node/core/server/string/ssrData.mjs +2 -2
- package/dist/esm-node/core/server/utils.mjs +52 -9
- package/dist/esm-node/document/cli/index.mjs +5 -6
- package/dist/esm-node/exports/head.mjs +144 -78
- package/dist/esm-node/exports/loadable.mjs +12 -6
- package/dist/esm-node/exports/tanstack-router.mjs +30 -3
- package/dist/esm-node/module-federation/index.mjs +110 -0
- package/dist/esm-node/router/cli/code/index.mjs +8 -48
- package/dist/esm-node/router/cli/code/templates.mjs +1 -14
- package/dist/esm-node/router/cli/handler.mjs +1 -1
- package/dist/esm-node/router/cli/index.mjs +3 -25
- package/dist/esm-node/router/runtime/DeferredDataScripts.node.mjs +16 -4
- package/dist/esm-node/router/runtime/PrefetchLink.mjs +152 -21
- package/dist/esm-node/router/runtime/internal.mjs +16 -15
- package/dist/esm-node/router/runtime/lifecycle.mjs +22 -13
- package/dist/esm-node/router/runtime/plugin.mjs +4 -11
- package/dist/esm-node/router/runtime/plugin.node.mjs +4 -9
- package/dist/esm-node/router/runtime/provider.mjs +58 -0
- package/dist/esm-node/router/runtime/rsc-router.mjs +10 -4
- package/dist/esm-node/router/runtime/utils.mjs +35 -10
- package/dist/types/cli/entry.d.ts +2 -2
- package/dist/types/cli/index.d.ts +3 -1
- package/dist/types/core/context/extensions.d.ts +37 -0
- package/dist/types/core/context/helmetContext.d.ts +10 -0
- package/dist/types/core/context/index.d.ts +6 -0
- package/dist/types/core/context/response/index.server.d.ts +4 -1
- package/dist/types/core/context/runtime.d.ts +1 -11
- package/dist/types/core/plugin/index.d.ts +1 -1
- package/dist/types/core/server/routerCleanup.d.ts +28 -0
- package/dist/types/core/server/scriptOrder.d.ts +24 -0
- package/dist/types/core/server/string/loadable.d.ts +1 -7
- package/dist/types/core/server/utils.d.ts +19 -1
- package/dist/types/document/constants.d.ts +3 -1
- package/dist/types/exports/head.d.ts +4 -4
- package/dist/types/exports/loadable.d.ts +1 -1
- package/dist/types/exports/tanstack-router.d.ts +88 -5
- package/dist/types/module-federation/index.d.ts +65 -0
- package/dist/types/router/cli/code/index.d.ts +1 -3
- package/dist/types/router/cli/code/utils.d.ts +1 -1
- package/dist/types/router/cli/entry.d.ts +1 -1
- package/dist/types/router/cli/handler.d.ts +0 -3
- package/dist/types/router/runtime/DeferredDataScripts.d.ts +1 -1
- package/dist/types/router/runtime/PrefetchLink.d.ts +5 -1
- package/dist/types/router/runtime/internal.d.ts +1 -0
- package/dist/types/router/runtime/lifecycle.d.ts +2 -0
- package/dist/types/router/runtime/plugin.d.ts +1 -1
- package/dist/types/router/runtime/plugin.node.d.ts +1 -1
- package/dist/types/router/runtime/provider.d.ts +61 -0
- package/package.json +34 -26
- package/rstest.config.mts +2 -4
- package/dist/cjs/router/cli/code/tanstackTypes.js +0 -443
- package/dist/cjs/router/runtime/tanstack/basepathRewrite.js +0 -62
- package/dist/cjs/router/runtime/tanstack/dataMutation.js +0 -345
- package/dist/cjs/router/runtime/tanstack/hydrationBoundary.js +0 -43
- package/dist/cjs/router/runtime/tanstack/plugin.js +0 -240
- package/dist/cjs/router/runtime/tanstack/plugin.node.js +0 -268
- package/dist/cjs/router/runtime/tanstack/prefetchLink.js +0 -55
- package/dist/cjs/router/runtime/tanstack/routeTree.js +0 -510
- package/dist/cjs/router/runtime/tanstack/rsc/ClientSlot.js +0 -53
- package/dist/cjs/router/runtime/tanstack/rsc/CompositeComponent.js +0 -75
- package/dist/cjs/router/runtime/tanstack/rsc/ReplayableStream.js +0 -141
- package/dist/cjs/router/runtime/tanstack/rsc/RscNodeRenderer.js +0 -65
- package/dist/cjs/router/runtime/tanstack/rsc/SlotContext.js +0 -54
- package/dist/cjs/router/runtime/tanstack/rsc/client.js +0 -93
- package/dist/cjs/router/runtime/tanstack/rsc/createRscProxy.js +0 -141
- package/dist/cjs/router/runtime/tanstack/rsc/index.js +0 -42
- package/dist/cjs/router/runtime/tanstack/rsc/server.js +0 -246
- package/dist/cjs/router/runtime/tanstack/rsc/slotUsageSanitizer.js +0 -65
- package/dist/cjs/router/runtime/tanstack/rsc/symbols.js +0 -72
- package/dist/cjs/ssr/index.node.js +0 -121
- package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +0 -84
- package/dist/cjs/ssr/serverRender/renderToString/entry.js +0 -196
- package/dist/cjs/ssr/serverRender/types.js +0 -36
- package/dist/esm/router/cli/code/tanstackTypes.mjs +0 -396
- package/dist/esm/router/runtime/tanstack/basepathRewrite.mjs +0 -28
- package/dist/esm/router/runtime/tanstack/dataMutation.mjs +0 -305
- package/dist/esm/router/runtime/tanstack/hydrationBoundary.mjs +0 -9
- package/dist/esm/router/runtime/tanstack/plugin.mjs +0 -206
- package/dist/esm/router/runtime/tanstack/plugin.node.mjs +0 -234
- package/dist/esm/router/runtime/tanstack/prefetchLink.mjs +0 -18
- package/dist/esm/router/runtime/tanstack/routeTree.mjs +0 -470
- package/dist/esm/router/runtime/tanstack/rsc/ClientSlot.mjs +0 -19
- package/dist/esm/router/runtime/tanstack/rsc/CompositeComponent.mjs +0 -41
- package/dist/esm/router/runtime/tanstack/rsc/ReplayableStream.mjs +0 -104
- package/dist/esm/router/runtime/tanstack/rsc/RscNodeRenderer.mjs +0 -31
- package/dist/esm/router/runtime/tanstack/rsc/SlotContext.mjs +0 -17
- package/dist/esm/router/runtime/tanstack/rsc/client.mjs +0 -53
- package/dist/esm/router/runtime/tanstack/rsc/createRscProxy.mjs +0 -107
- package/dist/esm/router/runtime/tanstack/rsc/index.mjs +0 -1
- package/dist/esm/router/runtime/tanstack/rsc/server.mjs +0 -200
- package/dist/esm/router/runtime/tanstack/rsc/slotUsageSanitizer.mjs +0 -31
- package/dist/esm/router/runtime/tanstack/rsc/symbols.mjs +0 -17
- package/dist/esm/ssr/index.node.mjs +0 -44
- package/dist/esm/ssr/serverRender/renderToStream/buildTemplate.after.mjs +0 -50
- package/dist/esm/ssr/serverRender/renderToString/entry.mjs +0 -151
- package/dist/esm/ssr/serverRender/types.mjs +0 -1
- package/dist/esm-node/router/cli/code/tanstackTypes.mjs +0 -397
- package/dist/esm-node/router/runtime/tanstack/basepathRewrite.mjs +0 -29
- package/dist/esm-node/router/runtime/tanstack/dataMutation.mjs +0 -306
- package/dist/esm-node/router/runtime/tanstack/hydrationBoundary.mjs +0 -10
- package/dist/esm-node/router/runtime/tanstack/plugin.mjs +0 -207
- package/dist/esm-node/router/runtime/tanstack/plugin.node.mjs +0 -235
- package/dist/esm-node/router/runtime/tanstack/prefetchLink.mjs +0 -19
- package/dist/esm-node/router/runtime/tanstack/routeTree.mjs +0 -471
- package/dist/esm-node/router/runtime/tanstack/rsc/ClientSlot.mjs +0 -20
- package/dist/esm-node/router/runtime/tanstack/rsc/CompositeComponent.mjs +0 -42
- package/dist/esm-node/router/runtime/tanstack/rsc/ReplayableStream.mjs +0 -105
- package/dist/esm-node/router/runtime/tanstack/rsc/RscNodeRenderer.mjs +0 -32
- package/dist/esm-node/router/runtime/tanstack/rsc/SlotContext.mjs +0 -18
- package/dist/esm-node/router/runtime/tanstack/rsc/client.mjs +0 -54
- package/dist/esm-node/router/runtime/tanstack/rsc/createRscProxy.mjs +0 -108
- package/dist/esm-node/router/runtime/tanstack/rsc/index.mjs +0 -2
- package/dist/esm-node/router/runtime/tanstack/rsc/server.mjs +0 -201
- package/dist/esm-node/router/runtime/tanstack/rsc/slotUsageSanitizer.mjs +0 -32
- package/dist/esm-node/router/runtime/tanstack/rsc/symbols.mjs +0 -18
- package/dist/esm-node/ssr/index.node.mjs +0 -45
- package/dist/esm-node/ssr/serverRender/renderToStream/buildTemplate.after.mjs +0 -51
- package/dist/esm-node/ssr/serverRender/renderToString/entry.mjs +0 -152
- package/dist/esm-node/ssr/serverRender/types.mjs +0 -2
- package/dist/types/router/cli/code/tanstackTypes.d.ts +0 -10
- package/dist/types/router/runtime/tanstack/basepathRewrite.d.ts +0 -8
- package/dist/types/router/runtime/tanstack/dataMutation.d.ts +0 -29
- package/dist/types/router/runtime/tanstack/hydrationBoundary.d.ts +0 -2
- package/dist/types/router/runtime/tanstack/plugin.d.ts +0 -6
- package/dist/types/router/runtime/tanstack/plugin.node.d.ts +0 -6
- package/dist/types/router/runtime/tanstack/prefetchLink.d.ts +0 -11
- package/dist/types/router/runtime/tanstack/routeTree.d.ts +0 -8
- package/dist/types/router/runtime/tanstack/rsc/ClientSlot.d.ts +0 -5
- package/dist/types/router/runtime/tanstack/rsc/CompositeComponent.d.ts +0 -3
- package/dist/types/router/runtime/tanstack/rsc/ReplayableStream.d.ts +0 -24
- package/dist/types/router/runtime/tanstack/rsc/RscNodeRenderer.d.ts +0 -5
- package/dist/types/router/runtime/tanstack/rsc/SlotContext.d.ts +0 -11
- package/dist/types/router/runtime/tanstack/rsc/client.d.ts +0 -11
- package/dist/types/router/runtime/tanstack/rsc/createRscProxy.d.ts +0 -7
- package/dist/types/router/runtime/tanstack/rsc/index.d.ts +0 -2
- package/dist/types/router/runtime/tanstack/rsc/server.d.ts +0 -14
- package/dist/types/router/runtime/tanstack/rsc/slotUsageSanitizer.d.ts +0 -2
- package/dist/types/router/runtime/tanstack/rsc/symbols.d.ts +0 -46
|
@@ -5,6 +5,21 @@ import { useEffect, useMemo, useRef } from "react";
|
|
|
5
5
|
import { ROUTER_DATA_JSON_ID } from "../../core/constants.mjs";
|
|
6
6
|
import { modernInline, runWindowFnStr } from "./constants.mjs";
|
|
7
7
|
import { serializeErrors } from "./utils.mjs";
|
|
8
|
+
function toDeferredErrorInfo(error) {
|
|
9
|
+
if ('production' === process.env.NODE_ENV) return {
|
|
10
|
+
message: 'Unexpected Server Error'
|
|
11
|
+
};
|
|
12
|
+
if (error && 'object' == typeof error) {
|
|
13
|
+
const maybeMessage = error.message;
|
|
14
|
+
return {
|
|
15
|
+
message: 'string' == typeof maybeMessage ? maybeMessage : String(maybeMessage ?? error),
|
|
16
|
+
stack: error.stack
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
message: String(error)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
8
23
|
const DeferredDataScripts = (props)=>{
|
|
9
24
|
const staticContext = props?.context;
|
|
10
25
|
const useJsonScript = props?.useJsonScript;
|
|
@@ -40,10 +55,7 @@ const DeferredDataScripts = (props)=>{
|
|
|
40
55
|
{
|
|
41
56
|
const trackedPromise = deferredData.data[key];
|
|
42
57
|
if (void 0 !== trackedPromise._error) {
|
|
43
|
-
const error =
|
|
44
|
-
message: trackedPromise._error.message,
|
|
45
|
-
stack: 'production' !== process.env.NODE_ENV ? trackedPromise._error.stack : void 0
|
|
46
|
-
};
|
|
58
|
+
const error = toDeferredErrorInfo(trackedPromise._error);
|
|
47
59
|
return {
|
|
48
60
|
key,
|
|
49
61
|
routerDataFnName: 'p',
|
|
@@ -11,45 +11,141 @@ function composeEventHandlers(theirHandler, ourHandler) {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const DEFAULT_PREFETCH_BEHAVIOR = 'render';
|
|
15
|
+
const INTENT_DELAY = 100;
|
|
16
|
+
const VIEWPORT_ROOT_MARGIN = '200px';
|
|
17
|
+
const MAX_CONCURRENT_WARMUPS = 4;
|
|
18
|
+
const WARMUP_TTL = 30000;
|
|
19
|
+
const SLOW_EFFECTIVE_TYPES = new Set([
|
|
20
|
+
'slow-2g',
|
|
21
|
+
'2g'
|
|
22
|
+
]);
|
|
23
|
+
const warmupCache = new Map();
|
|
24
|
+
const warmupQueue = [];
|
|
25
|
+
let activeWarmups = 0;
|
|
26
|
+
const getWarmupTimestamp = ()=>performance.now();
|
|
27
|
+
const getConnection = ()=>{
|
|
28
|
+
const nav = globalThis.navigator;
|
|
29
|
+
return nav?.connection || nav?.mozConnection || nav?.webkitConnection;
|
|
30
|
+
};
|
|
31
|
+
const shouldWarmupOnCurrentNetwork = ()=>{
|
|
32
|
+
const connection = getConnection();
|
|
33
|
+
if (connection?.saveData) return false;
|
|
34
|
+
if ('string' == typeof connection?.effectiveType && SLOW_EFFECTIVE_TYPES.has(connection.effectiveType)) return false;
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
37
|
+
const pruneWarmupCache = (now = getWarmupTimestamp())=>{
|
|
38
|
+
for (const [key, timestamp] of warmupCache)if (now - timestamp > WARMUP_TTL) warmupCache.delete(key);
|
|
39
|
+
};
|
|
40
|
+
const runNextWarmup = ()=>{
|
|
41
|
+
while(activeWarmups < MAX_CONCURRENT_WARMUPS && warmupQueue.length > 0){
|
|
42
|
+
const task = warmupQueue.shift();
|
|
43
|
+
if (task.cancelled) continue;
|
|
44
|
+
activeWarmups += 1;
|
|
45
|
+
task.run().catch((error)=>{
|
|
46
|
+
console.error(error);
|
|
47
|
+
warmupCache.delete(task.key);
|
|
48
|
+
}).finally(()=>{
|
|
49
|
+
activeWarmups -= 1;
|
|
50
|
+
runNextWarmup();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const scheduleWarmup = (key, run)=>{
|
|
55
|
+
if (!shouldWarmupOnCurrentNetwork()) return ()=>{};
|
|
56
|
+
pruneWarmupCache();
|
|
57
|
+
if (warmupCache.has(key)) return ()=>{};
|
|
58
|
+
warmupCache.set(key, getWarmupTimestamp());
|
|
59
|
+
const task = {
|
|
60
|
+
key,
|
|
61
|
+
run,
|
|
62
|
+
cancelled: false
|
|
63
|
+
};
|
|
64
|
+
warmupQueue.push(task);
|
|
65
|
+
runNextWarmup();
|
|
66
|
+
return ()=>{
|
|
67
|
+
task.cancelled = true;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
const setRef = (ref, value)=>{
|
|
71
|
+
if (!ref) return;
|
|
72
|
+
if ('function' == typeof ref) return void ref(value);
|
|
73
|
+
try {
|
|
74
|
+
ref.current = value;
|
|
75
|
+
} catch {}
|
|
76
|
+
};
|
|
77
|
+
const isDataWarmupEnabled = (route)=>{
|
|
78
|
+
const handle = route.handle;
|
|
79
|
+
return handle?.navigationWarmup?.data !== false;
|
|
80
|
+
};
|
|
81
|
+
function usePrefetchBehavior(prefetch, preload, theirElementProps) {
|
|
82
|
+
const [maybeWarmup, setMaybeWarmup] = react.useState(false);
|
|
16
83
|
const [shouldPrefetch, setShouldPrefetch] = react.useState(false);
|
|
84
|
+
const [shouldPreload, setShouldPreload] = react.useState(false);
|
|
85
|
+
const [viewportElement, setViewportElement] = react.useState(null);
|
|
17
86
|
const { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
|
|
18
87
|
react.useEffect(()=>{
|
|
19
88
|
if ('render' === prefetch) setShouldPrefetch(true);
|
|
89
|
+
if ('render' === preload) setShouldPreload(true);
|
|
20
90
|
}, [
|
|
21
|
-
prefetch
|
|
91
|
+
prefetch,
|
|
92
|
+
preload
|
|
22
93
|
]);
|
|
23
94
|
const setIntent = ()=>{
|
|
24
|
-
if ('intent' === prefetch)
|
|
95
|
+
if ('intent' === prefetch || 'intent' === preload) setMaybeWarmup(true);
|
|
25
96
|
};
|
|
26
97
|
const cancelIntent = ()=>{
|
|
27
|
-
if ('intent' === prefetch) {
|
|
28
|
-
|
|
98
|
+
if ('intent' === prefetch || 'intent' === preload) {
|
|
99
|
+
setMaybeWarmup(false);
|
|
29
100
|
setShouldPrefetch(false);
|
|
101
|
+
setShouldPreload(false);
|
|
30
102
|
}
|
|
31
103
|
};
|
|
32
104
|
react.useEffect(()=>{
|
|
33
|
-
if (
|
|
105
|
+
if (maybeWarmup) {
|
|
34
106
|
const id = setTimeout(()=>{
|
|
35
|
-
setShouldPrefetch(true);
|
|
36
|
-
|
|
107
|
+
if ('intent' === prefetch) setShouldPrefetch(true);
|
|
108
|
+
if ('intent' === preload) setShouldPreload(true);
|
|
109
|
+
}, INTENT_DELAY);
|
|
37
110
|
return ()=>{
|
|
38
111
|
clearTimeout(id);
|
|
39
112
|
};
|
|
40
113
|
}
|
|
41
114
|
}, [
|
|
42
|
-
|
|
115
|
+
maybeWarmup,
|
|
116
|
+
prefetch,
|
|
117
|
+
preload
|
|
118
|
+
]);
|
|
119
|
+
react.useEffect(()=>{
|
|
120
|
+
if (!viewportElement || 'viewport' !== prefetch && 'viewport' !== preload || "u" < typeof IntersectionObserver) return;
|
|
121
|
+
const observer = new IntersectionObserver((entries)=>{
|
|
122
|
+
if (!entries.some((entry)=>entry.isIntersecting)) return;
|
|
123
|
+
if ('viewport' === prefetch) setShouldPrefetch(true);
|
|
124
|
+
if ('viewport' === preload) setShouldPreload(true);
|
|
125
|
+
observer.disconnect();
|
|
126
|
+
}, {
|
|
127
|
+
rootMargin: VIEWPORT_ROOT_MARGIN
|
|
128
|
+
});
|
|
129
|
+
observer.observe(viewportElement);
|
|
130
|
+
return ()=>{
|
|
131
|
+
observer.disconnect();
|
|
132
|
+
};
|
|
133
|
+
}, [
|
|
134
|
+
prefetch,
|
|
135
|
+
preload,
|
|
136
|
+
viewportElement
|
|
43
137
|
]);
|
|
44
138
|
return [
|
|
45
139
|
shouldPrefetch,
|
|
140
|
+
shouldPreload,
|
|
46
141
|
{
|
|
47
142
|
onFocus: composeEventHandlers(onFocus, setIntent),
|
|
48
143
|
onBlur: composeEventHandlers(onBlur, cancelIntent),
|
|
49
144
|
onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),
|
|
50
145
|
onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
|
|
51
146
|
onTouchStart: composeEventHandlers(onTouchStart, setIntent)
|
|
52
|
-
}
|
|
147
|
+
},
|
|
148
|
+
setViewportElement
|
|
53
149
|
];
|
|
54
150
|
}
|
|
55
151
|
async function loadRouteModule(route, routeAssets) {
|
|
@@ -84,14 +180,34 @@ const getDataHref = (route, pathname, basename)=>{
|
|
|
84
180
|
const url = getRequestUrl(path, id);
|
|
85
181
|
return createDataHref(url.toString());
|
|
86
182
|
};
|
|
87
|
-
const PrefetchPageLinks = ({ path })=>{
|
|
183
|
+
const PrefetchPageLinks = ({ path, includeData })=>{
|
|
88
184
|
const { pathname } = path;
|
|
89
185
|
const context = useContext(InternalRuntimeContext);
|
|
90
186
|
const { routeManifest, routes } = context;
|
|
91
187
|
const { routeAssets } = routeManifest || {};
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
188
|
+
const allowNetworkWarmup = shouldWarmupOnCurrentNetwork();
|
|
189
|
+
const matches = useMemo(()=>Array.isArray(routes) ? matchRoutes(routes, pathname) : [], [
|
|
190
|
+
pathname,
|
|
191
|
+
routes
|
|
192
|
+
]);
|
|
193
|
+
react.useEffect(()=>{
|
|
194
|
+
if (!allowNetworkWarmup || !Array.isArray(matches) || !routeAssets || !__webpack_chunk_load__) return;
|
|
195
|
+
const cancellations = matches.map((match)=>{
|
|
196
|
+
const routeId = match.route.id;
|
|
197
|
+
const routeAsset = routeId ? routeAssets[routeId] : void 0;
|
|
198
|
+
const chunkIds = routeAsset?.chunkIds;
|
|
199
|
+
if (!routeId || !Array.isArray(chunkIds) || 0 === chunkIds.length) return ()=>{};
|
|
200
|
+
return scheduleWarmup(`route-module:${routeId}:${chunkIds.join(',')}`, ()=>loadRouteModule(match.route, routeAssets));
|
|
201
|
+
});
|
|
202
|
+
return ()=>{
|
|
203
|
+
cancellations.forEach((cancel)=>cancel());
|
|
204
|
+
};
|
|
205
|
+
}, [
|
|
206
|
+
allowNetworkWarmup,
|
|
207
|
+
matches,
|
|
208
|
+
routeAssets
|
|
209
|
+
]);
|
|
210
|
+
if (!allowNetworkWarmup || !includeData || !window._SSR_DATA) return null;
|
|
95
211
|
return /*#__PURE__*/ jsx(PrefetchDataLinks, {
|
|
96
212
|
matches: matches,
|
|
97
213
|
path: path,
|
|
@@ -103,7 +219,7 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
|
|
|
103
219
|
const currentMatches = useMatches();
|
|
104
220
|
const basename = useHref('/');
|
|
105
221
|
const dataHrefs = useMemo(()=>matches?.filter((match, index)=>{
|
|
106
|
-
if (!match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
|
|
222
|
+
if (!isDataWarmupEnabled(match.route) || !match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
|
|
107
223
|
if (match.route.shouldRevalidate) {
|
|
108
224
|
const currentUrl = new URL(location.pathname + location.search + location.hash, window.origin);
|
|
109
225
|
const nextUrl = new URL(pathname + search + hash, window.origin);
|
|
@@ -130,20 +246,35 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
|
|
|
130
246
|
children: dataHrefs
|
|
131
247
|
});
|
|
132
248
|
};
|
|
133
|
-
const
|
|
249
|
+
const normalizePreloadBehavior = (preload, prefetch)=>{
|
|
250
|
+
if (false === preload || 'none' === preload) return 'none';
|
|
251
|
+
if (void 0 !== preload) return preload;
|
|
252
|
+
if ('none' === prefetch) return 'none';
|
|
253
|
+
return prefetch;
|
|
254
|
+
};
|
|
255
|
+
const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch = DEFAULT_PREFETCH_BEHAVIOR, preload, ...props }, forwardedRef)=>{
|
|
134
256
|
const isAbsolute = 'string' == typeof to && ABSOLUTE_URL_REGEX.test(to);
|
|
135
|
-
const
|
|
257
|
+
const resolvedPreload = normalizePreloadBehavior(preload, prefetch);
|
|
258
|
+
const [shouldPrefetch, shouldPreload, prefetchHandlers, setViewportElement] = usePrefetchBehavior(prefetch, resolvedPreload, props);
|
|
259
|
+
const setAnchorRef = react.useCallback((element)=>{
|
|
260
|
+
setViewportElement(element);
|
|
261
|
+
setRef(forwardedRef, element);
|
|
262
|
+
}, [
|
|
263
|
+
forwardedRef,
|
|
264
|
+
setViewportElement
|
|
265
|
+
]);
|
|
136
266
|
const resolvedPath = useResolvedPath(to);
|
|
137
267
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
138
268
|
children: [
|
|
139
269
|
/*#__PURE__*/ jsx(Link, {
|
|
140
|
-
ref:
|
|
270
|
+
ref: setAnchorRef,
|
|
141
271
|
to: to,
|
|
142
272
|
...props,
|
|
143
273
|
...prefetchHandlers
|
|
144
274
|
}),
|
|
145
|
-
shouldPrefetch
|
|
146
|
-
path: resolvedPath
|
|
275
|
+
(shouldPrefetch || shouldPreload) && !isAbsolute ? /*#__PURE__*/ jsx(PrefetchPageLinks, {
|
|
276
|
+
path: resolvedPath,
|
|
277
|
+
includeData: shouldPrefetch
|
|
147
278
|
}) : null
|
|
148
279
|
]
|
|
149
280
|
});
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { merge } from "@modern-js/runtime-utils/merge";
|
|
3
|
-
import { modifyRoutes,
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import { modifyRoutes, routerPlugin } from "./plugin.mjs";
|
|
4
|
+
import { registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
|
|
5
|
+
registerRouterProvider('react-router', routerPlugin, {
|
|
6
|
+
isDefault: true
|
|
7
|
+
});
|
|
6
8
|
const internal_routerPlugin = (userConfig = {})=>({
|
|
7
9
|
name: '@modern-js/plugin-router',
|
|
8
|
-
registryHooks:
|
|
9
|
-
onAfterCreateRouter: onAfterCreateRouter,
|
|
10
|
-
onAfterHydrateRouter: onAfterHydrateRouter,
|
|
11
|
-
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
12
|
-
modifyRoutes: modifyRoutes,
|
|
13
|
-
onBeforeCreateRoutes: onBeforeCreateRoutes,
|
|
14
|
-
onBeforeHydrateRouter: onBeforeHydrateRouter
|
|
15
|
-
},
|
|
10
|
+
registryHooks: routerProviderRegistryHooks,
|
|
16
11
|
setup: (api)=>{
|
|
17
12
|
const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const pluginFactory = resolveRouterProvider(mergedConfig.framework, {
|
|
14
|
+
localDefault: {
|
|
15
|
+
name: 'react-router',
|
|
16
|
+
factory: routerPlugin
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const providerPlugin = pluginFactory(userConfig);
|
|
20
|
+
reportUnsupportedProviderRegistryHooks(providerPlugin);
|
|
21
|
+
providerPlugin.setup?.(api);
|
|
21
22
|
}
|
|
22
23
|
});
|
|
23
24
|
const internal = internal_routerPlugin;
|
|
24
25
|
export { renderRoutes } from "./utils.mjs";
|
|
25
26
|
export default internal;
|
|
26
|
-
export {
|
|
27
|
+
export { internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { createRuntimeContextExtension } from "../../core/context/extensions.mjs";
|
|
3
|
+
const routerRuntimeStateExtension = createRuntimeContextExtension('@modern-js/runtime:router-runtime-state');
|
|
4
|
+
const routerServerSnapshotExtension = createRuntimeContextExtension('@modern-js/runtime:router-server-snapshot');
|
|
5
|
+
function getRouterRuntimeState(runtimeContext) {
|
|
6
|
+
return routerRuntimeStateExtension.get(runtimeContext);
|
|
7
|
+
}
|
|
8
|
+
function getRouterServerSnapshot(runtimeContext) {
|
|
9
|
+
return routerServerSnapshotExtension.get(runtimeContext);
|
|
10
|
+
}
|
|
2
11
|
function toHydrationScripts(state) {
|
|
3
12
|
if (state.hydrationScripts?.length) return state.hydrationScripts;
|
|
4
13
|
return state.hydrationScript ? [
|
|
@@ -62,12 +71,8 @@ function createRouterRuntimeState(state) {
|
|
|
62
71
|
}
|
|
63
72
|
function applyRouterRuntimeState(runtimeContext, state) {
|
|
64
73
|
const normalized = createRouterRuntimeState(state);
|
|
65
|
-
runtimeContext
|
|
66
|
-
|
|
67
|
-
runtimeContext.routerHydrationScript = normalized.hydrationScript;
|
|
68
|
-
runtimeContext.routerMatchedRouteIds = normalized.matchedRouteIds;
|
|
69
|
-
runtimeContext.routerRuntime = normalized;
|
|
70
|
-
if (normalized.serverSnapshot) runtimeContext.routerServerSnapshot = normalized.serverSnapshot;
|
|
74
|
+
routerRuntimeStateExtension.set(runtimeContext, normalized);
|
|
75
|
+
if (normalized.serverSnapshot) routerServerSnapshotExtension.set(runtimeContext, normalized.serverSnapshot);
|
|
71
76
|
return runtimeContext;
|
|
72
77
|
}
|
|
73
78
|
function applyRouterServerPrepareResult(runtimeContext, result) {
|
|
@@ -80,18 +85,22 @@ function applyRouterServerPrepareResult(runtimeContext, result) {
|
|
|
80
85
|
return runtimeContext;
|
|
81
86
|
}
|
|
82
87
|
function getRouterHydrationScripts(runtimeContext) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
hydrationScript:
|
|
88
|
+
const serverSnapshot = getRouterServerSnapshot(runtimeContext);
|
|
89
|
+
const runtimeState = getRouterRuntimeState(runtimeContext);
|
|
90
|
+
return serverSnapshot?.hydrationScripts ?? toHydrationScripts({
|
|
91
|
+
hydrationScript: serverSnapshot?.hydrationScript
|
|
92
|
+
}) ?? runtimeState?.hydrationScripts ?? toHydrationScripts({
|
|
93
|
+
hydrationScript: runtimeState?.hydrationScript
|
|
87
94
|
}) ?? [];
|
|
88
95
|
}
|
|
89
96
|
function getRouterMatchedRouteIds(runtimeContext) {
|
|
90
|
-
|
|
97
|
+
const serverSnapshot = getRouterServerSnapshot(runtimeContext);
|
|
98
|
+
const runtimeState = getRouterRuntimeState(runtimeContext);
|
|
99
|
+
return serverSnapshot?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(serverSnapshot?.matches) ?? runtimeState?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(runtimeState?.matches);
|
|
91
100
|
}
|
|
92
101
|
async function cleanupRouterRuntimeState(runtimeContext) {
|
|
93
102
|
try {
|
|
94
|
-
await runtimeContext
|
|
103
|
+
await getRouterRuntimeState(runtimeContext)?.cleanup?.();
|
|
95
104
|
} catch {}
|
|
96
105
|
}
|
|
97
|
-
export { applyRouterRuntimeState, applyRouterServerPrepareResult, cleanupRouterRuntimeState, createRouterRuntimeState, createRouterServerSnapshot, getRouterHydrationScripts, getRouterMatchedRouteIds };
|
|
106
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, cleanupRouterRuntimeState, createRouterRuntimeState, createRouterServerSnapshot, getRouterHydrationScripts, getRouterMatchedRouteIds, getRouterRuntimeState, getRouterServerSnapshot };
|
|
@@ -5,15 +5,15 @@ import { RouterProvider, createBrowserRouter, createHashRouter, createRoutesFrom
|
|
|
5
5
|
import { normalizePathname } from "@modern-js/runtime-utils/url";
|
|
6
6
|
import * as __rspack_external_react from "react";
|
|
7
7
|
import { InternalRuntimeContext, getGlobalIsRscClient, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context/index.mjs";
|
|
8
|
-
import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
|
|
9
8
|
import { applyRouterRuntimeState } from "./lifecycle.mjs";
|
|
9
|
+
import { routerProviderRegistryHooks } from "./provider.mjs";
|
|
10
10
|
import { createClientRouterFromPayload } from "./rsc-router.mjs";
|
|
11
11
|
import { createRouteObjectsFromConfig, deserializeErrors, renderRoutes, urlJoin } from "./utils.mjs";
|
|
12
12
|
let finalRouteConfig = {
|
|
13
13
|
routes: []
|
|
14
14
|
};
|
|
15
15
|
let beforeCreateRouter = true;
|
|
16
|
-
function
|
|
16
|
+
function modifyRoutes(modifyFunction) {
|
|
17
17
|
if (beforeCreateRouter) {
|
|
18
18
|
const { routes: originRoutes } = finalRouteConfig;
|
|
19
19
|
const newRoutes = modifyFunction(originRoutes);
|
|
@@ -22,14 +22,7 @@ function plugin_modifyRoutes(modifyFunction) {
|
|
|
22
22
|
}
|
|
23
23
|
const routerPlugin = (userConfig = {})=>({
|
|
24
24
|
name: '@modern-js/plugin-router',
|
|
25
|
-
registryHooks:
|
|
26
|
-
onAfterCreateRouter: onAfterCreateRouter,
|
|
27
|
-
onAfterHydrateRouter: onAfterHydrateRouter,
|
|
28
|
-
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
29
|
-
modifyRoutes: modifyRoutes,
|
|
30
|
-
onBeforeCreateRoutes: onBeforeCreateRoutes,
|
|
31
|
-
onBeforeHydrateRouter: onBeforeHydrateRouter
|
|
32
|
-
},
|
|
25
|
+
registryHooks: routerProviderRegistryHooks,
|
|
33
26
|
setup: (api)=>{
|
|
34
27
|
const routesContainer = {
|
|
35
28
|
current: []
|
|
@@ -217,4 +210,4 @@ function useRouterCreation(props, options) {
|
|
|
217
210
|
getBlockNavState
|
|
218
211
|
]);
|
|
219
212
|
}
|
|
220
|
-
export { beforeCreateRouter, finalRouteConfig,
|
|
213
|
+
export { beforeCreateRouter, finalRouteConfig, modifyRoutes, routerPlugin };
|
|
@@ -9,8 +9,8 @@ import { useContext } from "react";
|
|
|
9
9
|
import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context/index.mjs";
|
|
10
10
|
import { setServerPayload } from "../../core/context/serverPayload/index.server.mjs";
|
|
11
11
|
import DeferredDataScripts_node from "./DeferredDataScripts.node.mjs";
|
|
12
|
-
import { modifyRoutes, onAfterCreateRouter, onBeforeCreateRouter, onBeforeCreateRoutes } from "./hooks.mjs";
|
|
13
12
|
import { applyRouterRuntimeState, createRouterServerSnapshot } from "./lifecycle.mjs";
|
|
13
|
+
import { routerProviderRegistryHooks } from "./provider.mjs";
|
|
14
14
|
import { RSCStaticRouter, createServerPayload, handleRSCRedirect, prepareRSCRoutes } from "./rsc-router.mjs";
|
|
15
15
|
import { createRouteObjectsFromConfig, renderRoutes, urlJoin } from "./utils.mjs";
|
|
16
16
|
function createRemixRequest(request) {
|
|
@@ -43,12 +43,7 @@ function createReactRouterServerSnapshot(routerContext, basename) {
|
|
|
43
43
|
}
|
|
44
44
|
const routerPlugin = (userConfig = {})=>({
|
|
45
45
|
name: '@modern-js/plugin-router',
|
|
46
|
-
registryHooks:
|
|
47
|
-
onAfterCreateRouter: onAfterCreateRouter,
|
|
48
|
-
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
49
|
-
modifyRoutes: modifyRoutes,
|
|
50
|
-
onBeforeCreateRoutes: onBeforeCreateRoutes
|
|
51
|
-
},
|
|
46
|
+
registryHooks: routerProviderRegistryHooks,
|
|
52
47
|
setup: (api)=>{
|
|
53
48
|
let finalRouteConfig = {};
|
|
54
49
|
api.onBeforeRender(async (context, interrupt)=>{
|
|
@@ -176,5 +171,5 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
176
171
|
});
|
|
177
172
|
}
|
|
178
173
|
});
|
|
179
|
-
const
|
|
180
|
-
export {
|
|
174
|
+
const modifyRoutes = ()=>{};
|
|
175
|
+
export { modifyRoutes, routerPlugin };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
|
|
3
|
+
const routerProviderRegistryHooks = {
|
|
4
|
+
modifyRoutes: modifyRoutes,
|
|
5
|
+
onBeforeCreateRoutes: onBeforeCreateRoutes,
|
|
6
|
+
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
7
|
+
onAfterCreateRouter: onAfterCreateRouter,
|
|
8
|
+
onBeforeHydrateRouter: onBeforeHydrateRouter,
|
|
9
|
+
onAfterHydrateRouter: onAfterHydrateRouter
|
|
10
|
+
};
|
|
11
|
+
function reportUnsupportedProviderRegistryHooks(providerPlugin) {
|
|
12
|
+
const unsupportedHookNames = Object.keys(providerPlugin.registryHooks ?? {}).filter((hookName)=>!(hookName in routerProviderRegistryHooks));
|
|
13
|
+
if (unsupportedHookNames.length > 0) console.warn(`[@modern-js/runtime] The router provider "${providerPlugin.name}" declares registry hooks outside the router hook contract: ${unsupportedHookNames.join(', ')}. These hooks are not registered when the provider is resolved through \`runtime.router.framework\` — declare them on a separate runtime plugin instead.`);
|
|
14
|
+
return unsupportedHookNames;
|
|
15
|
+
}
|
|
16
|
+
const REGISTRY_SLOT = Symbol.for('@modern-js/runtime:router-providers:v2');
|
|
17
|
+
function getRegistry() {
|
|
18
|
+
const host = globalThis;
|
|
19
|
+
host[REGISTRY_SLOT] ??= {
|
|
20
|
+
providers: new Map(),
|
|
21
|
+
warnedDuplicates: new Set()
|
|
22
|
+
};
|
|
23
|
+
host[REGISTRY_SLOT].warnedDuplicates ??= new Set();
|
|
24
|
+
return host[REGISTRY_SLOT];
|
|
25
|
+
}
|
|
26
|
+
function registerRouterProvider(name, factory, options = {}) {
|
|
27
|
+
const registry = getRegistry();
|
|
28
|
+
const existing = registry.providers.get(name);
|
|
29
|
+
if (void 0 !== existing) {
|
|
30
|
+
if (existing !== factory && !registry.warnedDuplicates.has(name)) {
|
|
31
|
+
registry.warnedDuplicates.add(name);
|
|
32
|
+
console.warn(`[@modern-js/runtime] The router provider "${name}" was registered more than once with different module instances; keeping the first registration. This usually means two copies of the providing plugin were bundled — for Module Federation, add the provider runtime (e.g. '@modern-js/plugin-tanstack/runtime') to the shared modules of both the host and the remote to deduplicate it.`);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (true !== options.isDefault) {
|
|
37
|
+
if (void 0 !== registry.nonDefaultProvider && registry.nonDefaultProvider !== name) throw new Error(`[@modern-js/runtime] Cannot register router provider "${name}": the competing router provider "${registry.nonDefaultProvider}" is already registered. Only one non-default router provider may be installed at a time — remove one of the router plugins.`);
|
|
38
|
+
registry.nonDefaultProvider = name;
|
|
39
|
+
} else registry.defaultProvider = name;
|
|
40
|
+
registry.providers.set(name, factory);
|
|
41
|
+
}
|
|
42
|
+
function resolveRouterProvider(framework, options = {}) {
|
|
43
|
+
const registry = getRegistry();
|
|
44
|
+
const name = framework || registry.defaultProvider || options.localDefault?.name;
|
|
45
|
+
if (void 0 === name) throw new Error('[@modern-js/runtime] No default router provider is registered. This is a bug in the runtime setup.');
|
|
46
|
+
if (void 0 !== options.localDefault && name === options.localDefault.name) return options.localDefault.factory;
|
|
47
|
+
const factory = registry.providers.get(name);
|
|
48
|
+
if (void 0 !== factory) return factory;
|
|
49
|
+
if ('tanstack' === name) throw new Error("[@modern-js/runtime] `runtime.router.framework` is set to \"tanstack\", but no TanStack router provider is registered. Install @modern-js/plugin-tanstack, add `tanstackRouterPlugin()` to the `plugins` array in modern.config.ts, and make sure '@modern-js/plugin-tanstack/runtime' is imported (e.g. in modern.runtime.ts).");
|
|
50
|
+
throw new Error(`[@modern-js/runtime] Unknown router framework "${name}". Registered providers: ${[
|
|
51
|
+
...registry.providers.keys()
|
|
52
|
+
].join(', ') || '(none)'}. Install and register the plugin that provides this router framework.`);
|
|
53
|
+
}
|
|
54
|
+
function unsafe_resetRouterProvidersForTesting() {
|
|
55
|
+
const host = globalThis;
|
|
56
|
+
delete host[REGISTRY_SLOT];
|
|
57
|
+
}
|
|
58
|
+
export { registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks, unsafe_resetRouterProvidersForTesting };
|
|
@@ -9,6 +9,7 @@ const safeUse = (value)=>{
|
|
|
9
9
|
if ('function' == typeof reactUse) return reactUse(value);
|
|
10
10
|
return null;
|
|
11
11
|
};
|
|
12
|
+
const hasRouteErrorBoundary = (route)=>Boolean(route.errorElement || route.ErrorBoundary);
|
|
12
13
|
function collectCssFilesFromRoutes(matches, routes) {
|
|
13
14
|
const cssFiles = [];
|
|
14
15
|
for (const match of matches){
|
|
@@ -70,7 +71,7 @@ const createServerPayload = (routerContext, routes)=>{
|
|
|
70
71
|
errorElement: route.errorElement,
|
|
71
72
|
handle: route.handle,
|
|
72
73
|
hasAction: !!route.action,
|
|
73
|
-
hasErrorBoundary:
|
|
74
|
+
hasErrorBoundary: hasRouteErrorBoundary(route),
|
|
74
75
|
hasLoader: !!route.loader,
|
|
75
76
|
hasClientLoader: !!route.hasClientLoader,
|
|
76
77
|
id: route.id,
|
|
@@ -133,6 +134,12 @@ const mergeRoutes = (routes, originalRoutes)=>{
|
|
|
133
134
|
});
|
|
134
135
|
return mergeRoutesRecursive(originalRoutes);
|
|
135
136
|
};
|
|
137
|
+
const toReactRouterRoute = (route)=>{
|
|
138
|
+
const { hasErrorBoundary: _hasErrorBoundary, children, ...routeObject } = route;
|
|
139
|
+
const sanitizedRoute = routeObject;
|
|
140
|
+
if (children && Array.isArray(children)) sanitizedRoute.children = children.map(toReactRouterRoute);
|
|
141
|
+
return sanitizedRoute;
|
|
142
|
+
};
|
|
136
143
|
const findRouteInTree = (routes, routeId)=>{
|
|
137
144
|
for (const route of routes){
|
|
138
145
|
if (route.id === routeId) return route;
|
|
@@ -253,7 +260,7 @@ const createClientRouterFromPayload = (payload, originalRoutes, basename = '')=>
|
|
|
253
260
|
if (matchedRoute) {
|
|
254
261
|
const modernMatch = match.route;
|
|
255
262
|
router.patchRoutes(matchedRoute.parentId ?? null, [
|
|
256
|
-
matchedRoute
|
|
263
|
+
toReactRouterRoute(matchedRoute)
|
|
257
264
|
], true);
|
|
258
265
|
if (modernMatch.isClientComponent && modernMatch.Component) delete modernMatch.Component;
|
|
259
266
|
}
|
|
@@ -286,7 +293,6 @@ const createRSCStaticRouterComponent = (payload, basename)=>{
|
|
|
286
293
|
id: match.id,
|
|
287
294
|
action: match.hasAction || !!match.clientAction,
|
|
288
295
|
handle: match.handle,
|
|
289
|
-
hasErrorBoundary: match.hasErrorBoundary,
|
|
290
296
|
loader: match.hasLoader || !!match.clientLoader,
|
|
291
297
|
index: match.index,
|
|
292
298
|
path: match.path,
|
|
@@ -305,7 +311,7 @@ const createRSCStaticRouterComponent = (payload, basename)=>{
|
|
|
305
311
|
route
|
|
306
312
|
];
|
|
307
313
|
}, []);
|
|
308
|
-
const router = createStaticRouter(processedRoutes, routerContext);
|
|
314
|
+
const router = createStaticRouter(processedRoutes.map(toReactRouterRoute), routerContext);
|
|
309
315
|
return /*#__PURE__*/ jsx(StaticRouterProvider, {
|
|
310
316
|
context: routerContext,
|
|
311
317
|
router: router,
|
|
@@ -61,7 +61,6 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
|
61
61
|
id: route.id,
|
|
62
62
|
loader: route.loader,
|
|
63
63
|
action: route.action,
|
|
64
|
-
hasErrorBoundary: route.hasErrorBoundary,
|
|
65
64
|
shouldRevalidate: route.shouldRevalidate,
|
|
66
65
|
handle: {
|
|
67
66
|
...route.handle,
|
|
@@ -99,7 +98,10 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
|
99
98
|
}
|
|
100
99
|
routeObjects.push({
|
|
101
100
|
path: '*',
|
|
102
|
-
element: /*#__PURE__*/ jsx(DefaultNotFound, {})
|
|
101
|
+
element: /*#__PURE__*/ jsx(DefaultNotFound, {}),
|
|
102
|
+
loader: ()=>new Response('404', {
|
|
103
|
+
status: 404
|
|
104
|
+
})
|
|
103
105
|
});
|
|
104
106
|
return routeObjects;
|
|
105
107
|
}
|
|
@@ -148,17 +150,40 @@ function serializeErrors(errors) {
|
|
|
148
150
|
if (!errors) return null;
|
|
149
151
|
const entries = Object.entries(errors);
|
|
150
152
|
const serialized = {};
|
|
151
|
-
for (const [key, val] of entries)if (isRouteErrorResponse(val)) serialized[key] =
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
for (const [key, val] of entries)if (isRouteErrorResponse(val)) serialized[key] = serializeRouteErrorResponse(val);
|
|
154
|
+
else if (val instanceof Error) serialized[key] = serializeError(val);
|
|
155
|
+
else serialized[key] = val;
|
|
156
|
+
return serialized;
|
|
157
|
+
}
|
|
158
|
+
function shouldRedactServerError() {
|
|
159
|
+
return 'development' !== process.env.NODE_ENV && 'test' !== process.env.NODE_ENV;
|
|
160
|
+
}
|
|
161
|
+
function serializeError(error) {
|
|
162
|
+
if (shouldRedactServerError()) return {
|
|
163
|
+
message: 'Unexpected Server Error',
|
|
164
|
+
stack: void 0,
|
|
165
|
+
__type: 'Error'
|
|
154
166
|
};
|
|
155
|
-
|
|
156
|
-
message:
|
|
157
|
-
stack:
|
|
167
|
+
return {
|
|
168
|
+
message: error.message,
|
|
169
|
+
stack: error.stack,
|
|
158
170
|
__type: 'Error'
|
|
159
171
|
};
|
|
160
|
-
|
|
161
|
-
|
|
172
|
+
}
|
|
173
|
+
function serializeRouteErrorResponse(error) {
|
|
174
|
+
if (!isRouteErrorResponse(error)) return error;
|
|
175
|
+
if (error.status >= 500 && shouldRedactServerError()) return {
|
|
176
|
+
status: error.status,
|
|
177
|
+
statusText: 'Internal Server Error',
|
|
178
|
+
data: 'Unexpected Server Error',
|
|
179
|
+
__type: 'RouteErrorResponse'
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
status: error.status,
|
|
183
|
+
statusText: error.statusText,
|
|
184
|
+
data: error.data,
|
|
185
|
+
__type: 'RouteErrorResponse'
|
|
186
|
+
};
|
|
162
187
|
}
|
|
163
188
|
function deserializeErrors(errors) {
|
|
164
189
|
if (!errors) return null;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const hasApp: (dir: string) =>
|
|
2
|
-
export declare const isRuntimeEntry: (dir: string) =>
|
|
1
|
+
export declare const hasApp: (dir: string) => string | false;
|
|
2
|
+
export declare const isRuntimeEntry: (dir: string) => string | false;
|
|
@@ -2,7 +2,9 @@ import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
|
2
2
|
import { documentPlugin } from '../document/cli';
|
|
3
3
|
import { routerPlugin } from '../router/cli';
|
|
4
4
|
import { ssrPlugin } from './ssr';
|
|
5
|
-
export { getEntrypointRoutesDir, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, } from '../router/cli';
|
|
5
|
+
export { getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, } from '../router/cli';
|
|
6
|
+
export { makeLegalIdentifier } from '../router/cli/code/makeLegalIdentifier';
|
|
7
|
+
export { getPathWithoutExt } from '../router/cli/code/utils';
|
|
6
8
|
export { isRuntimeEntry } from './entry';
|
|
7
9
|
export { documentPlugin, routerPlugin, ssrPlugin };
|
|
8
10
|
export declare const runtimePlugin: (params?: {
|