@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
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
const MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT = 'modernjs:mf-runtime-fallback';
|
|
2
|
+
const MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT = 'modernjs:mf-runtime-recovery';
|
|
3
|
+
const DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT = '/_modern/contract-gates/runtime-fallback';
|
|
4
|
+
const DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER = 'x-modernjs-runtime-signal-token';
|
|
5
|
+
class ModuleFederationRemoteLoadTimeoutError extends Error {
|
|
6
|
+
constructor(remote, timeoutMs){
|
|
7
|
+
super(`Loading remote "${remote}" timed out after ${timeoutMs}ms`);
|
|
8
|
+
this.name = 'ModuleFederationRemoteLoadTimeoutError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
class ModuleFederationRemoteLoadError extends Error {
|
|
12
|
+
constructor(remote, attempts, causeError){
|
|
13
|
+
super(`Unable to load remote "${remote}" after ${attempts} attempt${attempts > 1 ? 's' : ''}: ${causeError.message}`);
|
|
14
|
+
this.name = 'ModuleFederationRemoteLoadError';
|
|
15
|
+
this.remote = remote;
|
|
16
|
+
this.attempts = attempts;
|
|
17
|
+
this.causeError = causeError;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
class ModuleFederationRemoteComponentContractError extends Error {
|
|
21
|
+
constructor(remote, exportName){
|
|
22
|
+
super(`Remote "${remote}" export "${exportName}" is not a valid React component`);
|
|
23
|
+
this.name = 'ModuleFederationRemoteComponentContractError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function toError(error) {
|
|
27
|
+
if (error instanceof Error) return error;
|
|
28
|
+
return new Error('string' == typeof error ? error : 'Unknown remote load error');
|
|
29
|
+
}
|
|
30
|
+
function classifyModuleFederationFallback(error) {
|
|
31
|
+
const normalizedError = toError(error);
|
|
32
|
+
if (normalizedError instanceof ModuleFederationRemoteLoadError) return classifyModuleFederationFallback(normalizedError.causeError);
|
|
33
|
+
if (normalizedError instanceof ModuleFederationRemoteLoadTimeoutError) return 'timeout';
|
|
34
|
+
if (normalizedError instanceof ModuleFederationRemoteComponentContractError) return 'contract';
|
|
35
|
+
const message = normalizedError.message;
|
|
36
|
+
if (/version|requiredVersion|singleton|share scope|shared module/i.test(message)) return 'version-skew';
|
|
37
|
+
if (/network|fetch|script|timeout|chunk|loading/i.test(message)) return 'network';
|
|
38
|
+
return 'remote-unavailable';
|
|
39
|
+
}
|
|
40
|
+
function createModuleFederationFallbackTelemetry(input) {
|
|
41
|
+
const error = void 0 !== input.error ? toError(input.error) : void 0;
|
|
42
|
+
const status = input.status ?? 'degraded';
|
|
43
|
+
const eventName = input.eventName ?? ('recovered' === status ? MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT : MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT);
|
|
44
|
+
const metadata = {
|
|
45
|
+
...input.metadata ?? {},
|
|
46
|
+
classification: input.classification,
|
|
47
|
+
remote: input.remote,
|
|
48
|
+
status
|
|
49
|
+
};
|
|
50
|
+
if (void 0 !== input.exportName) metadata.exportName = input.exportName;
|
|
51
|
+
if (void 0 !== input.runtimeDigest) metadata.runtimeDigest = input.runtimeDigest;
|
|
52
|
+
if (void 0 !== error) {
|
|
53
|
+
metadata.errorName = error.name;
|
|
54
|
+
metadata.errorMessage = error.message;
|
|
55
|
+
}
|
|
56
|
+
const payload = {
|
|
57
|
+
appName: input.appName,
|
|
58
|
+
eventName,
|
|
59
|
+
metadata,
|
|
60
|
+
phase: input.phase,
|
|
61
|
+
reason: input.classification,
|
|
62
|
+
schemaVersion: 1
|
|
63
|
+
};
|
|
64
|
+
if (void 0 !== input.entry) payload.entry = input.entry;
|
|
65
|
+
if (void 0 !== input.runtimeDigest) payload.runtimeDigest = input.runtimeDigest;
|
|
66
|
+
return payload;
|
|
67
|
+
}
|
|
68
|
+
function toModuleFederationFallbackAttributes(payload) {
|
|
69
|
+
return {
|
|
70
|
+
'data-mf-fallback-app': payload.appName,
|
|
71
|
+
'data-mf-fallback-classification': payload.reason,
|
|
72
|
+
'data-mf-fallback-phase': payload.phase,
|
|
73
|
+
'data-mf-fallback-remote': String(payload.metadata.remote),
|
|
74
|
+
'data-mf-fallback-status': String(payload.metadata.status),
|
|
75
|
+
'data-mf-telemetry-event': payload.eventName
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function emitModuleFederationFallbackTelemetry(input, options = {}) {
|
|
79
|
+
const payload = createModuleFederationFallbackTelemetry(input);
|
|
80
|
+
if ("u" > typeof window && 'function' == typeof window.dispatchEvent && "u" > typeof CustomEvent) window.dispatchEvent(new CustomEvent(payload.eventName, {
|
|
81
|
+
detail: payload
|
|
82
|
+
}));
|
|
83
|
+
const shouldPost = true === options.postSignal || Boolean(options.endpoint);
|
|
84
|
+
if (!shouldPost) return {
|
|
85
|
+
dispatched: true,
|
|
86
|
+
posted: false
|
|
87
|
+
};
|
|
88
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
89
|
+
if ('function' != typeof fetchImpl) return {
|
|
90
|
+
dispatched: true,
|
|
91
|
+
posted: false
|
|
92
|
+
};
|
|
93
|
+
const headers = new Headers({
|
|
94
|
+
'content-type': 'application/json'
|
|
95
|
+
});
|
|
96
|
+
if (void 0 !== options.authToken && options.authToken.length > 0) headers.set(options.authHeaderName ?? DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER, options.authToken);
|
|
97
|
+
const response = await fetchImpl(options.endpoint ?? DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT, {
|
|
98
|
+
body: JSON.stringify(payload),
|
|
99
|
+
headers,
|
|
100
|
+
method: 'POST',
|
|
101
|
+
keepalive: true
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
dispatched: true,
|
|
105
|
+
posted: true,
|
|
106
|
+
postStatus: response.status
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export { DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER, DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT, MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT, MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT, ModuleFederationRemoteComponentContractError, ModuleFederationRemoteLoadError, ModuleFederationRemoteLoadTimeoutError, classifyModuleFederationFallback, createModuleFederationFallbackTelemetry, emitModuleFederationFallbackTelemetry, toModuleFederationFallbackAttributes };
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { filterRoutesForServer, filterRoutesLoader, fs, getEntryOptions, isUseRsc, isUseSSRBundle, logger, markRoutes } from "@modern-js/utils";
|
|
1
|
+
import { collectRouteComponentFiles, filterRoutesForServer, filterRoutesLoader, fs, getEntryOptions, isUseRsc, isUseSSRBundle, logger, markRoutes } from "@modern-js/utils";
|
|
2
2
|
import { cloneDeep } from "@modern-js/utils/lodash";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME } from "../../../cli/constants.mjs";
|
|
5
5
|
import { resolveSSRMode } from "../../../cli/ssr/mode.mjs";
|
|
6
6
|
import { FILE_SYSTEM_ROUTES_FILE_NAME } from "../constants.mjs";
|
|
7
7
|
import { walk } from "./nestedRoutes.mjs";
|
|
8
|
-
import { generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled } from "./tanstackTypes.mjs";
|
|
9
8
|
import { getServerCombinedModuleFile, getServerLoadersFile } from "./utils.mjs";
|
|
10
9
|
import * as __rspack_external__templates_mjs_4da4c6c8 from "./templates.mjs";
|
|
11
10
|
async function generateRoutesForEntry(entrypoint, appContext) {
|
|
@@ -40,42 +39,15 @@ async function generateRoutesForEntry(entrypoint, appContext) {
|
|
|
40
39
|
}
|
|
41
40
|
return routes;
|
|
42
41
|
}
|
|
43
|
-
const generateCode = async (appContext, config, entrypoints, api
|
|
42
|
+
const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
44
43
|
const { internalDirectory, srcDirectory, internalSrcAlias, packageName } = appContext;
|
|
45
44
|
const hooks = api.getHooks();
|
|
46
|
-
const enableTanstackTypes = options?.enableTanstackTypes ?? await isTanstackRouterFrameworkEnabled(appContext);
|
|
47
45
|
const generatedRoutesByEntry = {};
|
|
46
|
+
const eagerRouteComponentFilesByEntry = new Map();
|
|
48
47
|
await Promise.all(entrypoints.map(generateEntryCode));
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const registerEntries = allEntries.sort((a, b)=>{
|
|
53
|
-
if (mainEntry && a === mainEntry) return -1;
|
|
54
|
-
if (mainEntry && b === mainEntry) return 1;
|
|
55
|
-
return a.localeCompare(b);
|
|
56
|
-
});
|
|
57
|
-
if (registerEntries.length > 0) {
|
|
58
|
-
const registerDtsPath = path.join(srcDirectory, 'modern-tanstack', 'register.gen.d.ts');
|
|
59
|
-
const importStatements = registerEntries.map((entryName, index)=>`import type { router as router${index} } from './${entryName}/router.gen';`).join('\n');
|
|
60
|
-
const routerUnionType = registerEntries.map((_, index)=>`typeof router${index}`).join(' | ');
|
|
61
|
-
const registerContent = `// This file is auto-generated by Modern.js. Do not edit manually.
|
|
62
|
-
|
|
63
|
-
${importStatements}
|
|
64
|
-
|
|
65
|
-
declare module '@modern-js/runtime/tanstack-router' {
|
|
66
|
-
interface Register {
|
|
67
|
-
router: ${routerUnionType};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
`;
|
|
71
|
-
try {
|
|
72
|
-
const prev = await fs.pathExists(registerDtsPath) ? await fs.readFile(registerDtsPath, 'utf-8') : null;
|
|
73
|
-
if (prev !== registerContent) await fs.outputFile(registerDtsPath, registerContent, 'utf-8');
|
|
74
|
-
} catch {
|
|
75
|
-
await fs.outputFile(registerDtsPath, registerContent, 'utf-8');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
48
|
+
api.updateAppContext({
|
|
49
|
+
eagerRouteComponentFilesByEntry
|
|
50
|
+
});
|
|
79
51
|
async function generateEntryCode(entrypoint) {
|
|
80
52
|
const { entryName, isMainEntry, isAutoMount, pageRoutesEntry, nestedRoutesEntry } = entrypoint;
|
|
81
53
|
const { metaName } = api.getAppContext();
|
|
@@ -106,6 +78,8 @@ declare module '@modern-js/runtime/tanstack-router' {
|
|
|
106
78
|
routes: markedRoutes
|
|
107
79
|
});
|
|
108
80
|
generatedRoutesByEntry[entryName] = routes;
|
|
81
|
+
const routeEagerFilesForEntry = collectRouteComponentFiles(routes, srcDirectory, internalSrcAlias);
|
|
82
|
+
eagerRouteComponentFilesByEntry.set(entryName, routeEagerFilesForEntry);
|
|
109
83
|
if ('stream' === ssrMode) {
|
|
110
84
|
const hasPageRoute = routes.some((route)=>'type' in route && 'page' === route.type);
|
|
111
85
|
if (hasPageRoute) {
|
|
@@ -157,20 +131,6 @@ declare module '@modern-js/runtime/tanstack-router' {
|
|
|
157
131
|
await fs.outputFile(serverLoaderFile, serverLoaderCombined);
|
|
158
132
|
}
|
|
159
133
|
await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`), code, 'utf8');
|
|
160
|
-
if (enableTanstackTypes) {
|
|
161
|
-
const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
|
|
162
|
-
appContext,
|
|
163
|
-
entryName,
|
|
164
|
-
routes: routes
|
|
165
|
-
});
|
|
166
|
-
const outPath = path.join(srcDirectory, 'modern-tanstack', entryName, 'router.gen.ts');
|
|
167
|
-
try {
|
|
168
|
-
const prev = await fs.pathExists(outPath) ? await fs.readFile(outPath, 'utf-8') : null;
|
|
169
|
-
if (prev !== routerGenTs) await fs.outputFile(outPath, routerGenTs, 'utf-8');
|
|
170
|
-
} catch {
|
|
171
|
-
await fs.outputFile(outPath, routerGenTs, 'utf-8');
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
134
|
}
|
|
175
135
|
}
|
|
176
136
|
}
|
|
@@ -100,20 +100,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
100
100
|
const loadersMapFile = path.join(internalDirectory, entryName, TEMP_LOADERS_DIR, 'map.json');
|
|
101
101
|
const importLazyCode = `
|
|
102
102
|
import { lazy } from "react";
|
|
103
|
-
import
|
|
104
|
-
|
|
105
|
-
const resolveLoadableExport = module => {
|
|
106
|
-
const candidates = [module, module.default, module.default?.default];
|
|
107
|
-
const loadable = candidates.find(candidate => typeof candidate === 'function');
|
|
108
|
-
|
|
109
|
-
if (!loadable) {
|
|
110
|
-
throw new TypeError('Modern.js runtime loadable export must resolve to a function');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return loadable;
|
|
114
|
-
};
|
|
115
|
-
const loadable = resolveLoadableExport(loadableModule);
|
|
116
|
-
const loadableLazy = loadableModule.lazy || loadableModule.default?.lazy || loadable.lazy;
|
|
103
|
+
import loadable, { lazy as loadableLazy } from "@${metaName}/runtime/loadable"
|
|
117
104
|
`;
|
|
118
105
|
let rootLayoutCode = "";
|
|
119
106
|
const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId, inValidSSRRoute })=>{
|
|
@@ -20,7 +20,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
|
|
|
20
20
|
const { generatorRegisterCode, generateCode, generatorServerRegisterCode } = await import("./code/index.mjs");
|
|
21
21
|
originEntrypointsByKey.set(entrypointsKey, cloneDeep(entrypoints));
|
|
22
22
|
const enableRsc = resolvedConfig?.server?.rsc;
|
|
23
|
-
const routesByEntry = await generateCode(appContext, resolvedConfig, entrypoints, api
|
|
23
|
+
const routesByEntry = await generateCode(appContext, resolvedConfig, entrypoints, api);
|
|
24
24
|
await Promise.all(entrypoints.map(async (entrypoint)=>{
|
|
25
25
|
if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
|
|
26
26
|
const route = appContext.serverRoutes.find((r)=>r.entryName === entrypoint.entryName);
|
|
@@ -1,28 +1,8 @@
|
|
|
1
1
|
import node_path from "node:path";
|
|
2
|
-
import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer,
|
|
2
|
+
import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer, fs } from "@modern-js/utils";
|
|
3
3
|
import { NESTED_ROUTES_DIR } from "./constants.mjs";
|
|
4
4
|
import { BUILT_IN_ROUTES_OWNER, getEntrypointRoutesDir, getEntrypointRoutesOwner, isRouteEntry } from "./entry.mjs";
|
|
5
5
|
import { handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints } from "./handler.mjs";
|
|
6
|
-
const JS_OR_TS_EXTS = [
|
|
7
|
-
'.js',
|
|
8
|
-
'.jsx',
|
|
9
|
-
'.ts',
|
|
10
|
-
'.tsx',
|
|
11
|
-
'.mjs',
|
|
12
|
-
'.mts',
|
|
13
|
-
'.cjs',
|
|
14
|
-
'.cts'
|
|
15
|
-
];
|
|
16
|
-
function hasRouterConfigInRuntimeFile(runtimeConfigBase) {
|
|
17
|
-
const runtimeConfigFile = findExists(JS_OR_TS_EXTS.map((ext)=>`${runtimeConfigBase}${ext}`));
|
|
18
|
-
if (!runtimeConfigFile) return false;
|
|
19
|
-
try {
|
|
20
|
-
const content = fs.readFileSync(runtimeConfigFile, 'utf-8');
|
|
21
|
-
return /router\s*:/.test(content);
|
|
22
|
-
} catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
6
|
function isBuiltInRouteEntrypoint(entrypoint) {
|
|
27
7
|
const entrypointRoutesOwner = getEntrypointRoutesOwner(entrypoint);
|
|
28
8
|
if (entrypointRoutesOwner) return entrypointRoutesOwner === BUILT_IN_ROUTES_OWNER;
|
|
@@ -52,12 +32,11 @@ const routerPlugin = ()=>({
|
|
|
52
32
|
});
|
|
53
33
|
});
|
|
54
34
|
api._internalRuntimePlugins(({ entrypoint, plugins })=>{
|
|
55
|
-
const { serverRoutes, metaName
|
|
35
|
+
const { serverRoutes, metaName } = api.getAppContext();
|
|
56
36
|
const normalizedConfig = api.getNormalizedConfig();
|
|
57
37
|
const hasUserRouterConfig = normalizedConfig.router && Object.keys(normalizedConfig.router).length > 0;
|
|
58
|
-
const hasRuntimeRouterConfig = hasRouterConfigInRuntimeFile(node_path.join(srcDirectory, runtimeConfigFile));
|
|
59
38
|
const serverBase = serverRoutes.filter((route)=>route.entryName === entrypoint.entryName).map((route)=>route.urlPath).sort((a, b)=>a.length - b.length > 0 ? -1 : 1);
|
|
60
|
-
const shouldInstallBuiltInRouter = isBuiltInRouteEntrypoint(entrypoint) || !isPluginOwnedRouteEntrypoint(entrypoint) &&
|
|
39
|
+
const shouldInstallBuiltInRouter = isBuiltInRouteEntrypoint(entrypoint) || !isPluginOwnedRouteEntrypoint(entrypoint) && hasUserRouterConfig;
|
|
61
40
|
if (shouldInstallBuiltInRouter) plugins.push({
|
|
62
41
|
name: 'router',
|
|
63
42
|
path: `@${metaName}/runtime/router/internal`,
|
|
@@ -78,7 +57,6 @@ const routerPlugin = ()=>({
|
|
|
78
57
|
source: {
|
|
79
58
|
include: [
|
|
80
59
|
/[\\/]node_modules[\\/]react-router[\\/]/,
|
|
81
|
-
/[\\/]node_modules[\\/]react-router-dom[\\/]/,
|
|
82
60
|
node_path.resolve(__dirname, '../runtime').replace('cjs', 'esm')
|
|
83
61
|
]
|
|
84
62
|
}
|
|
@@ -4,6 +4,21 @@ import { useEffect, useMemo, useRef } from "react";
|
|
|
4
4
|
import { ROUTER_DATA_JSON_ID } from "../../core/constants.mjs";
|
|
5
5
|
import { modernInline, runWindowFnStr } from "./constants.mjs";
|
|
6
6
|
import { serializeErrors } from "./utils.mjs";
|
|
7
|
+
function toDeferredErrorInfo(error) {
|
|
8
|
+
if ('production' === process.env.NODE_ENV) return {
|
|
9
|
+
message: 'Unexpected Server Error'
|
|
10
|
+
};
|
|
11
|
+
if (error && 'object' == typeof error) {
|
|
12
|
+
const maybeMessage = error.message;
|
|
13
|
+
return {
|
|
14
|
+
message: 'string' == typeof maybeMessage ? maybeMessage : String(maybeMessage ?? error),
|
|
15
|
+
stack: error.stack
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
message: String(error)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
7
22
|
const DeferredDataScripts = (props)=>{
|
|
8
23
|
const staticContext = props?.context;
|
|
9
24
|
const useJsonScript = props?.useJsonScript;
|
|
@@ -39,10 +54,7 @@ const DeferredDataScripts = (props)=>{
|
|
|
39
54
|
{
|
|
40
55
|
const trackedPromise = deferredData.data[key];
|
|
41
56
|
if (void 0 !== trackedPromise._error) {
|
|
42
|
-
const error =
|
|
43
|
-
message: trackedPromise._error.message,
|
|
44
|
-
stack: 'production' !== process.env.NODE_ENV ? trackedPromise._error.stack : void 0
|
|
45
|
-
};
|
|
57
|
+
const error = toDeferredErrorInfo(trackedPromise._error);
|
|
46
58
|
return {
|
|
47
59
|
key,
|
|
48
60
|
routerDataFnName: 'p',
|
|
@@ -10,45 +10,141 @@ function composeEventHandlers(theirHandler, ourHandler) {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const DEFAULT_PREFETCH_BEHAVIOR = 'render';
|
|
14
|
+
const INTENT_DELAY = 100;
|
|
15
|
+
const VIEWPORT_ROOT_MARGIN = '200px';
|
|
16
|
+
const MAX_CONCURRENT_WARMUPS = 4;
|
|
17
|
+
const WARMUP_TTL = 30000;
|
|
18
|
+
const SLOW_EFFECTIVE_TYPES = new Set([
|
|
19
|
+
'slow-2g',
|
|
20
|
+
'2g'
|
|
21
|
+
]);
|
|
22
|
+
const warmupCache = new Map();
|
|
23
|
+
const warmupQueue = [];
|
|
24
|
+
let activeWarmups = 0;
|
|
25
|
+
const getWarmupTimestamp = ()=>performance.now();
|
|
26
|
+
const getConnection = ()=>{
|
|
27
|
+
const nav = globalThis.navigator;
|
|
28
|
+
return nav?.connection || nav?.mozConnection || nav?.webkitConnection;
|
|
29
|
+
};
|
|
30
|
+
const shouldWarmupOnCurrentNetwork = ()=>{
|
|
31
|
+
const connection = getConnection();
|
|
32
|
+
if (connection?.saveData) return false;
|
|
33
|
+
if ('string' == typeof connection?.effectiveType && SLOW_EFFECTIVE_TYPES.has(connection.effectiveType)) return false;
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
const pruneWarmupCache = (now = getWarmupTimestamp())=>{
|
|
37
|
+
for (const [key, timestamp] of warmupCache)if (now - timestamp > WARMUP_TTL) warmupCache.delete(key);
|
|
38
|
+
};
|
|
39
|
+
const runNextWarmup = ()=>{
|
|
40
|
+
while(activeWarmups < MAX_CONCURRENT_WARMUPS && warmupQueue.length > 0){
|
|
41
|
+
const task = warmupQueue.shift();
|
|
42
|
+
if (task.cancelled) continue;
|
|
43
|
+
activeWarmups += 1;
|
|
44
|
+
task.run().catch((error)=>{
|
|
45
|
+
console.error(error);
|
|
46
|
+
warmupCache.delete(task.key);
|
|
47
|
+
}).finally(()=>{
|
|
48
|
+
activeWarmups -= 1;
|
|
49
|
+
runNextWarmup();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const scheduleWarmup = (key, run)=>{
|
|
54
|
+
if (!shouldWarmupOnCurrentNetwork()) return ()=>{};
|
|
55
|
+
pruneWarmupCache();
|
|
56
|
+
if (warmupCache.has(key)) return ()=>{};
|
|
57
|
+
warmupCache.set(key, getWarmupTimestamp());
|
|
58
|
+
const task = {
|
|
59
|
+
key,
|
|
60
|
+
run,
|
|
61
|
+
cancelled: false
|
|
62
|
+
};
|
|
63
|
+
warmupQueue.push(task);
|
|
64
|
+
runNextWarmup();
|
|
65
|
+
return ()=>{
|
|
66
|
+
task.cancelled = true;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
const setRef = (ref, value)=>{
|
|
70
|
+
if (!ref) return;
|
|
71
|
+
if ('function' == typeof ref) return void ref(value);
|
|
72
|
+
try {
|
|
73
|
+
ref.current = value;
|
|
74
|
+
} catch {}
|
|
75
|
+
};
|
|
76
|
+
const isDataWarmupEnabled = (route)=>{
|
|
77
|
+
const handle = route.handle;
|
|
78
|
+
return handle?.navigationWarmup?.data !== false;
|
|
79
|
+
};
|
|
80
|
+
function usePrefetchBehavior(prefetch, preload, theirElementProps) {
|
|
81
|
+
const [maybeWarmup, setMaybeWarmup] = react.useState(false);
|
|
15
82
|
const [shouldPrefetch, setShouldPrefetch] = react.useState(false);
|
|
83
|
+
const [shouldPreload, setShouldPreload] = react.useState(false);
|
|
84
|
+
const [viewportElement, setViewportElement] = react.useState(null);
|
|
16
85
|
const { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
|
|
17
86
|
react.useEffect(()=>{
|
|
18
87
|
if ('render' === prefetch) setShouldPrefetch(true);
|
|
88
|
+
if ('render' === preload) setShouldPreload(true);
|
|
19
89
|
}, [
|
|
20
|
-
prefetch
|
|
90
|
+
prefetch,
|
|
91
|
+
preload
|
|
21
92
|
]);
|
|
22
93
|
const setIntent = ()=>{
|
|
23
|
-
if ('intent' === prefetch)
|
|
94
|
+
if ('intent' === prefetch || 'intent' === preload) setMaybeWarmup(true);
|
|
24
95
|
};
|
|
25
96
|
const cancelIntent = ()=>{
|
|
26
|
-
if ('intent' === prefetch) {
|
|
27
|
-
|
|
97
|
+
if ('intent' === prefetch || 'intent' === preload) {
|
|
98
|
+
setMaybeWarmup(false);
|
|
28
99
|
setShouldPrefetch(false);
|
|
100
|
+
setShouldPreload(false);
|
|
29
101
|
}
|
|
30
102
|
};
|
|
31
103
|
react.useEffect(()=>{
|
|
32
|
-
if (
|
|
104
|
+
if (maybeWarmup) {
|
|
33
105
|
const id = setTimeout(()=>{
|
|
34
|
-
setShouldPrefetch(true);
|
|
35
|
-
|
|
106
|
+
if ('intent' === prefetch) setShouldPrefetch(true);
|
|
107
|
+
if ('intent' === preload) setShouldPreload(true);
|
|
108
|
+
}, INTENT_DELAY);
|
|
36
109
|
return ()=>{
|
|
37
110
|
clearTimeout(id);
|
|
38
111
|
};
|
|
39
112
|
}
|
|
40
113
|
}, [
|
|
41
|
-
|
|
114
|
+
maybeWarmup,
|
|
115
|
+
prefetch,
|
|
116
|
+
preload
|
|
117
|
+
]);
|
|
118
|
+
react.useEffect(()=>{
|
|
119
|
+
if (!viewportElement || 'viewport' !== prefetch && 'viewport' !== preload || "u" < typeof IntersectionObserver) return;
|
|
120
|
+
const observer = new IntersectionObserver((entries)=>{
|
|
121
|
+
if (!entries.some((entry)=>entry.isIntersecting)) return;
|
|
122
|
+
if ('viewport' === prefetch) setShouldPrefetch(true);
|
|
123
|
+
if ('viewport' === preload) setShouldPreload(true);
|
|
124
|
+
observer.disconnect();
|
|
125
|
+
}, {
|
|
126
|
+
rootMargin: VIEWPORT_ROOT_MARGIN
|
|
127
|
+
});
|
|
128
|
+
observer.observe(viewportElement);
|
|
129
|
+
return ()=>{
|
|
130
|
+
observer.disconnect();
|
|
131
|
+
};
|
|
132
|
+
}, [
|
|
133
|
+
prefetch,
|
|
134
|
+
preload,
|
|
135
|
+
viewportElement
|
|
42
136
|
]);
|
|
43
137
|
return [
|
|
44
138
|
shouldPrefetch,
|
|
139
|
+
shouldPreload,
|
|
45
140
|
{
|
|
46
141
|
onFocus: composeEventHandlers(onFocus, setIntent),
|
|
47
142
|
onBlur: composeEventHandlers(onBlur, cancelIntent),
|
|
48
143
|
onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),
|
|
49
144
|
onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
|
|
50
145
|
onTouchStart: composeEventHandlers(onTouchStart, setIntent)
|
|
51
|
-
}
|
|
146
|
+
},
|
|
147
|
+
setViewportElement
|
|
52
148
|
];
|
|
53
149
|
}
|
|
54
150
|
async function loadRouteModule(route, routeAssets) {
|
|
@@ -83,14 +179,34 @@ const getDataHref = (route, pathname, basename)=>{
|
|
|
83
179
|
const url = getRequestUrl(path, id);
|
|
84
180
|
return createDataHref(url.toString());
|
|
85
181
|
};
|
|
86
|
-
const PrefetchPageLinks = ({ path })=>{
|
|
182
|
+
const PrefetchPageLinks = ({ path, includeData })=>{
|
|
87
183
|
const { pathname } = path;
|
|
88
184
|
const context = useContext(InternalRuntimeContext);
|
|
89
185
|
const { routeManifest, routes } = context;
|
|
90
186
|
const { routeAssets } = routeManifest || {};
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
187
|
+
const allowNetworkWarmup = shouldWarmupOnCurrentNetwork();
|
|
188
|
+
const matches = useMemo(()=>Array.isArray(routes) ? matchRoutes(routes, pathname) : [], [
|
|
189
|
+
pathname,
|
|
190
|
+
routes
|
|
191
|
+
]);
|
|
192
|
+
react.useEffect(()=>{
|
|
193
|
+
if (!allowNetworkWarmup || !Array.isArray(matches) || !routeAssets || !__webpack_chunk_load__) return;
|
|
194
|
+
const cancellations = matches.map((match)=>{
|
|
195
|
+
const routeId = match.route.id;
|
|
196
|
+
const routeAsset = routeId ? routeAssets[routeId] : void 0;
|
|
197
|
+
const chunkIds = routeAsset?.chunkIds;
|
|
198
|
+
if (!routeId || !Array.isArray(chunkIds) || 0 === chunkIds.length) return ()=>{};
|
|
199
|
+
return scheduleWarmup(`route-module:${routeId}:${chunkIds.join(',')}`, ()=>loadRouteModule(match.route, routeAssets));
|
|
200
|
+
});
|
|
201
|
+
return ()=>{
|
|
202
|
+
cancellations.forEach((cancel)=>cancel());
|
|
203
|
+
};
|
|
204
|
+
}, [
|
|
205
|
+
allowNetworkWarmup,
|
|
206
|
+
matches,
|
|
207
|
+
routeAssets
|
|
208
|
+
]);
|
|
209
|
+
if (!allowNetworkWarmup || !includeData || !window._SSR_DATA) return null;
|
|
94
210
|
return /*#__PURE__*/ jsx(PrefetchDataLinks, {
|
|
95
211
|
matches: matches,
|
|
96
212
|
path: path,
|
|
@@ -102,7 +218,7 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
|
|
|
102
218
|
const currentMatches = useMatches();
|
|
103
219
|
const basename = useHref('/');
|
|
104
220
|
const dataHrefs = useMemo(()=>matches?.filter((match, index)=>{
|
|
105
|
-
if (!match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
|
|
221
|
+
if (!isDataWarmupEnabled(match.route) || !match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
|
|
106
222
|
if (match.route.shouldRevalidate) {
|
|
107
223
|
const currentUrl = new URL(location.pathname + location.search + location.hash, window.origin);
|
|
108
224
|
const nextUrl = new URL(pathname + search + hash, window.origin);
|
|
@@ -129,20 +245,35 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
|
|
|
129
245
|
children: dataHrefs
|
|
130
246
|
});
|
|
131
247
|
};
|
|
132
|
-
const
|
|
248
|
+
const normalizePreloadBehavior = (preload, prefetch)=>{
|
|
249
|
+
if (false === preload || 'none' === preload) return 'none';
|
|
250
|
+
if (void 0 !== preload) return preload;
|
|
251
|
+
if ('none' === prefetch) return 'none';
|
|
252
|
+
return prefetch;
|
|
253
|
+
};
|
|
254
|
+
const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch = DEFAULT_PREFETCH_BEHAVIOR, preload, ...props }, forwardedRef)=>{
|
|
133
255
|
const isAbsolute = 'string' == typeof to && ABSOLUTE_URL_REGEX.test(to);
|
|
134
|
-
const
|
|
256
|
+
const resolvedPreload = normalizePreloadBehavior(preload, prefetch);
|
|
257
|
+
const [shouldPrefetch, shouldPreload, prefetchHandlers, setViewportElement] = usePrefetchBehavior(prefetch, resolvedPreload, props);
|
|
258
|
+
const setAnchorRef = react.useCallback((element)=>{
|
|
259
|
+
setViewportElement(element);
|
|
260
|
+
setRef(forwardedRef, element);
|
|
261
|
+
}, [
|
|
262
|
+
forwardedRef,
|
|
263
|
+
setViewportElement
|
|
264
|
+
]);
|
|
135
265
|
const resolvedPath = useResolvedPath(to);
|
|
136
266
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
137
267
|
children: [
|
|
138
268
|
/*#__PURE__*/ jsx(Link, {
|
|
139
|
-
ref:
|
|
269
|
+
ref: setAnchorRef,
|
|
140
270
|
to: to,
|
|
141
271
|
...props,
|
|
142
272
|
...prefetchHandlers
|
|
143
273
|
}),
|
|
144
|
-
shouldPrefetch
|
|
145
|
-
path: resolvedPath
|
|
274
|
+
(shouldPrefetch || shouldPreload) && !isAbsolute ? /*#__PURE__*/ jsx(PrefetchPageLinks, {
|
|
275
|
+
path: resolvedPath,
|
|
276
|
+
includeData: shouldPrefetch
|
|
146
277
|
}) : null
|
|
147
278
|
]
|
|
148
279
|
});
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import { merge } from "@modern-js/runtime-utils/merge";
|
|
2
|
-
import { modifyRoutes,
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { modifyRoutes, routerPlugin } from "./plugin.mjs";
|
|
3
|
+
import { registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
|
|
4
|
+
registerRouterProvider('react-router', routerPlugin, {
|
|
5
|
+
isDefault: true
|
|
6
|
+
});
|
|
5
7
|
const internal_routerPlugin = (userConfig = {})=>({
|
|
6
8
|
name: '@modern-js/plugin-router',
|
|
7
|
-
registryHooks:
|
|
8
|
-
onAfterCreateRouter: onAfterCreateRouter,
|
|
9
|
-
onAfterHydrateRouter: onAfterHydrateRouter,
|
|
10
|
-
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
11
|
-
modifyRoutes: modifyRoutes,
|
|
12
|
-
onBeforeCreateRoutes: onBeforeCreateRoutes,
|
|
13
|
-
onBeforeHydrateRouter: onBeforeHydrateRouter
|
|
14
|
-
},
|
|
9
|
+
registryHooks: routerProviderRegistryHooks,
|
|
15
10
|
setup: (api)=>{
|
|
16
11
|
const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
const pluginFactory = resolveRouterProvider(mergedConfig.framework, {
|
|
13
|
+
localDefault: {
|
|
14
|
+
name: 'react-router',
|
|
15
|
+
factory: routerPlugin
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const providerPlugin = pluginFactory(userConfig);
|
|
19
|
+
reportUnsupportedProviderRegistryHooks(providerPlugin);
|
|
20
|
+
providerPlugin.setup?.(api);
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
23
|
const internal = internal_routerPlugin;
|
|
23
24
|
export { renderRoutes } from "./utils.mjs";
|
|
24
25
|
export default internal;
|
|
25
|
-
export {
|
|
26
|
+
export { internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import { createRuntimeContextExtension } from "../../core/context/extensions.mjs";
|
|
2
|
+
const routerRuntimeStateExtension = createRuntimeContextExtension('@modern-js/runtime:router-runtime-state');
|
|
3
|
+
const routerServerSnapshotExtension = createRuntimeContextExtension('@modern-js/runtime:router-server-snapshot');
|
|
4
|
+
function getRouterRuntimeState(runtimeContext) {
|
|
5
|
+
return routerRuntimeStateExtension.get(runtimeContext);
|
|
6
|
+
}
|
|
7
|
+
function getRouterServerSnapshot(runtimeContext) {
|
|
8
|
+
return routerServerSnapshotExtension.get(runtimeContext);
|
|
9
|
+
}
|
|
1
10
|
function toHydrationScripts(state) {
|
|
2
11
|
if (state.hydrationScripts?.length) return state.hydrationScripts;
|
|
3
12
|
return state.hydrationScript ? [
|
|
@@ -61,12 +70,8 @@ function createRouterRuntimeState(state) {
|
|
|
61
70
|
}
|
|
62
71
|
function applyRouterRuntimeState(runtimeContext, state) {
|
|
63
72
|
const normalized = createRouterRuntimeState(state);
|
|
64
|
-
runtimeContext
|
|
65
|
-
|
|
66
|
-
runtimeContext.routerHydrationScript = normalized.hydrationScript;
|
|
67
|
-
runtimeContext.routerMatchedRouteIds = normalized.matchedRouteIds;
|
|
68
|
-
runtimeContext.routerRuntime = normalized;
|
|
69
|
-
if (normalized.serverSnapshot) runtimeContext.routerServerSnapshot = normalized.serverSnapshot;
|
|
73
|
+
routerRuntimeStateExtension.set(runtimeContext, normalized);
|
|
74
|
+
if (normalized.serverSnapshot) routerServerSnapshotExtension.set(runtimeContext, normalized.serverSnapshot);
|
|
70
75
|
return runtimeContext;
|
|
71
76
|
}
|
|
72
77
|
function applyRouterServerPrepareResult(runtimeContext, result) {
|
|
@@ -79,18 +84,22 @@ function applyRouterServerPrepareResult(runtimeContext, result) {
|
|
|
79
84
|
return runtimeContext;
|
|
80
85
|
}
|
|
81
86
|
function getRouterHydrationScripts(runtimeContext) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
hydrationScript:
|
|
87
|
+
const serverSnapshot = getRouterServerSnapshot(runtimeContext);
|
|
88
|
+
const runtimeState = getRouterRuntimeState(runtimeContext);
|
|
89
|
+
return serverSnapshot?.hydrationScripts ?? toHydrationScripts({
|
|
90
|
+
hydrationScript: serverSnapshot?.hydrationScript
|
|
91
|
+
}) ?? runtimeState?.hydrationScripts ?? toHydrationScripts({
|
|
92
|
+
hydrationScript: runtimeState?.hydrationScript
|
|
86
93
|
}) ?? [];
|
|
87
94
|
}
|
|
88
95
|
function getRouterMatchedRouteIds(runtimeContext) {
|
|
89
|
-
|
|
96
|
+
const serverSnapshot = getRouterServerSnapshot(runtimeContext);
|
|
97
|
+
const runtimeState = getRouterRuntimeState(runtimeContext);
|
|
98
|
+
return serverSnapshot?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(serverSnapshot?.matches) ?? runtimeState?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(runtimeState?.matches);
|
|
90
99
|
}
|
|
91
100
|
async function cleanupRouterRuntimeState(runtimeContext) {
|
|
92
101
|
try {
|
|
93
|
-
await runtimeContext
|
|
102
|
+
await getRouterRuntimeState(runtimeContext)?.cleanup?.();
|
|
94
103
|
} catch {}
|
|
95
104
|
}
|
|
96
|
-
export { applyRouterRuntimeState, applyRouterServerPrepareResult, cleanupRouterRuntimeState, createRouterRuntimeState, createRouterServerSnapshot, getRouterHydrationScripts, getRouterMatchedRouteIds };
|
|
105
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, cleanupRouterRuntimeState, createRouterRuntimeState, createRouterServerSnapshot, getRouterHydrationScripts, getRouterMatchedRouteIds, getRouterRuntimeState, getRouterServerSnapshot };
|