@bleedingdev/modern-js-runtime 3.5.0-ultramodern.10 → 3.5.0-ultramodern.100

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.
Files changed (151) hide show
  1. package/dist/cjs/boundary-debugger/index.js +13 -3
  2. package/dist/cjs/cli/index.js +1 -11
  3. package/dist/cjs/cli/registry.js +18 -0
  4. package/dist/cjs/cli/ssr/index.js +3 -2
  5. package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +8 -4
  6. package/dist/cjs/core/browser/hydrate.js +16 -2
  7. package/dist/cjs/core/browser/index.js +19 -18
  8. package/dist/cjs/core/context/index.js +3 -0
  9. package/dist/cjs/core/context/public.js +49 -0
  10. package/dist/cjs/core/context/runtime.js +6 -8
  11. package/dist/cjs/core/react/wrapper.js +57 -0
  12. package/dist/cjs/core/server/federatedCss.js +7 -3
  13. package/dist/cjs/core/server/requestHandler.js +15 -45
  14. package/dist/cjs/core/server/requestResponse.js +83 -0
  15. package/dist/cjs/core/server/routerCleanup.js +16 -6
  16. package/dist/cjs/core/server/scriptOrder.js +13 -10
  17. package/dist/cjs/core/server/stream/afterTemplate.js +9 -5
  18. package/dist/cjs/core/server/stream/template.js +3 -3
  19. package/dist/cjs/core/server/string/index.js +3 -3
  20. package/dist/cjs/core/server/string/loadable.js +3 -11
  21. package/dist/cjs/index.js +7 -6
  22. package/dist/cjs/module-federation/consume-surface.js +199 -0
  23. package/dist/cjs/module-federation/distributed-ssr.js +134 -0
  24. package/dist/cjs/module-federation/index.js +258 -120
  25. package/dist/cjs/module-federation/last-known-good.js +124 -0
  26. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +140 -0
  27. package/dist/cjs/module-federation/surface-resolution-types.js +61 -0
  28. package/dist/cjs/router/cli/code/nestedRoutes.js +3 -0
  29. package/dist/cjs/router/cli/code/templates.js +3 -2
  30. package/dist/cjs/router/cli/constants.js +1 -0
  31. package/dist/cjs/router/cli/nestedRoutesSpec.js +3 -1
  32. package/dist/cjs/router/runtime/hooks.js +7 -6
  33. package/dist/cjs/router/runtime/internal.js +30 -16
  34. package/dist/cjs/router/runtime/plugin.js +6 -7
  35. package/dist/cjs/router/runtime/provider.js +58 -12
  36. package/dist/esm/boundary-debugger/index.mjs +13 -3
  37. package/dist/esm/cli/code.mjs +12 -12
  38. package/dist/esm/cli/index.mjs +2 -12
  39. package/dist/esm/cli/registry.mjs +0 -0
  40. package/dist/esm/cli/ssr/index.mjs +3 -2
  41. package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +8 -4
  42. package/dist/esm/core/browser/hydrate.mjs +15 -4
  43. package/dist/esm/core/browser/index.mjs +15 -17
  44. package/dist/esm/core/context/index.mjs +1 -1
  45. package/dist/esm/core/context/public.mjs +5 -0
  46. package/dist/esm/core/context/runtime.mjs +4 -6
  47. package/dist/esm/core/react/wrapper.mjs +58 -1
  48. package/dist/esm/core/server/federatedCss.mjs +7 -3
  49. package/dist/esm/core/server/requestHandler.mjs +15 -45
  50. package/dist/esm/core/server/requestResponse.mjs +39 -0
  51. package/dist/esm/core/server/routerCleanup.mjs +11 -4
  52. package/dist/esm/core/server/scriptOrder.mjs +11 -8
  53. package/dist/esm/core/server/stream/afterTemplate.mjs +10 -6
  54. package/dist/esm/core/server/stream/template.mjs +3 -3
  55. package/dist/esm/core/server/string/index.mjs +3 -3
  56. package/dist/esm/core/server/string/loadable.mjs +3 -8
  57. package/dist/esm/exports/loadable.mjs +3 -3
  58. package/dist/esm/index.mjs +2 -1
  59. package/dist/esm/module-federation/consume-surface.mjs +158 -0
  60. package/dist/esm/module-federation/distributed-ssr.mjs +81 -0
  61. package/dist/esm/module-federation/index.mjs +6 -0
  62. package/dist/esm/module-federation/last-known-good.mjs +80 -0
  63. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +100 -0
  64. package/dist/esm/module-federation/surface-resolution-types.mjs +8 -0
  65. package/dist/esm/router/cli/code/index.mjs +5 -5
  66. package/dist/esm/router/cli/code/nestedRoutes.mjs +3 -0
  67. package/dist/esm/router/cli/code/templates.mjs +3 -2
  68. package/dist/esm/router/cli/constants.mjs +1 -0
  69. package/dist/esm/router/cli/handler.mjs +3 -3
  70. package/dist/esm/router/cli/nestedRoutesSpec.mjs +3 -1
  71. package/dist/esm/router/runtime/hooks.mjs +7 -6
  72. package/dist/esm/router/runtime/internal.mjs +26 -18
  73. package/dist/esm/router/runtime/plugin.mjs +6 -7
  74. package/dist/esm/router/runtime/provider.mjs +56 -13
  75. package/dist/esm-node/boundary-debugger/index.mjs +13 -3
  76. package/dist/esm-node/cli/code.mjs +12 -12
  77. package/dist/esm-node/cli/index.mjs +2 -12
  78. package/dist/esm-node/cli/registry.mjs +1 -0
  79. package/dist/esm-node/cli/ssr/index.mjs +3 -2
  80. package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +8 -4
  81. package/dist/esm-node/core/browser/hydrate.mjs +15 -4
  82. package/dist/esm-node/core/browser/index.mjs +15 -17
  83. package/dist/esm-node/core/context/index.mjs +1 -1
  84. package/dist/esm-node/core/context/public.mjs +6 -0
  85. package/dist/esm-node/core/context/runtime.mjs +4 -6
  86. package/dist/esm-node/core/react/wrapper.mjs +58 -1
  87. package/dist/esm-node/core/server/federatedCss.mjs +7 -3
  88. package/dist/esm-node/core/server/requestHandler.mjs +15 -45
  89. package/dist/esm-node/core/server/requestResponse.mjs +40 -0
  90. package/dist/esm-node/core/server/routerCleanup.mjs +11 -4
  91. package/dist/esm-node/core/server/scriptOrder.mjs +11 -8
  92. package/dist/esm-node/core/server/stream/afterTemplate.mjs +10 -6
  93. package/dist/esm-node/core/server/stream/template.mjs +3 -3
  94. package/dist/esm-node/core/server/string/index.mjs +3 -3
  95. package/dist/esm-node/core/server/string/loadable.mjs +3 -8
  96. package/dist/esm-node/exports/loadable.mjs +3 -3
  97. package/dist/esm-node/index.mjs +2 -1
  98. package/dist/esm-node/module-federation/consume-surface.mjs +159 -0
  99. package/dist/esm-node/module-federation/distributed-ssr.mjs +82 -0
  100. package/dist/esm-node/module-federation/index.mjs +6 -0
  101. package/dist/esm-node/module-federation/last-known-good.mjs +81 -0
  102. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +101 -0
  103. package/dist/esm-node/module-federation/surface-resolution-types.mjs +9 -0
  104. package/dist/esm-node/router/cli/code/index.mjs +5 -5
  105. package/dist/esm-node/router/cli/code/nestedRoutes.mjs +3 -0
  106. package/dist/esm-node/router/cli/code/templates.mjs +3 -2
  107. package/dist/esm-node/router/cli/constants.mjs +1 -0
  108. package/dist/esm-node/router/cli/handler.mjs +3 -3
  109. package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +3 -1
  110. package/dist/esm-node/router/runtime/hooks.mjs +7 -6
  111. package/dist/esm-node/router/runtime/internal.mjs +26 -18
  112. package/dist/esm-node/router/runtime/plugin.mjs +6 -7
  113. package/dist/esm-node/router/runtime/provider.mjs +56 -13
  114. package/dist/types/boundary-debugger/index.d.ts +1 -1
  115. package/dist/types/cli/registry.d.ts +2 -0
  116. package/dist/types/common.d.ts +8 -1
  117. package/dist/types/core/browser/hydrate.d.ts +2 -1
  118. package/dist/types/core/browser/index.d.ts +4 -1
  119. package/dist/types/core/context/index.d.ts +26 -10
  120. package/dist/types/core/context/monitors/default.d.ts +10 -2
  121. package/dist/types/core/context/monitors/index.d.ts +1 -1
  122. package/dist/types/core/context/monitors/index.server.d.ts +2 -2
  123. package/dist/types/core/context/public.d.ts +27 -0
  124. package/dist/types/core/context/runtime.d.ts +12 -22
  125. package/dist/types/core/react/index.d.ts +1 -1
  126. package/dist/types/core/server/requestResponse.d.ts +15 -0
  127. package/dist/types/core/server/routerCleanup.d.ts +2 -1
  128. package/dist/types/core/server/scriptOrder.d.ts +1 -1
  129. package/dist/types/core/server/stream/shared.d.ts +2 -2
  130. package/dist/types/core/server/string/loadable.d.ts +0 -2
  131. package/dist/types/exports/head.d.ts +1 -1
  132. package/dist/types/index.d.ts +5 -5
  133. package/dist/types/internal.d.ts +0 -1
  134. package/dist/types/module-federation/consume-surface.d.ts +104 -0
  135. package/dist/types/module-federation/distributed-ssr.d.ts +61 -0
  136. package/dist/types/module-federation/index.d.ts +6 -0
  137. package/dist/types/module-federation/last-known-good.d.ts +72 -0
  138. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +25 -0
  139. package/dist/types/module-federation/surface-resolution-types.d.ts +23 -0
  140. package/dist/types/router/cli/constants.d.ts +1 -0
  141. package/dist/types/router/runtime/hooks.d.ts +10 -6
  142. package/dist/types/router/runtime/internal.d.ts +13 -3
  143. package/dist/types/router/runtime/plugin.d.ts +1 -1
  144. package/dist/types/router/runtime/plugin.node.d.ts +1 -1
  145. package/dist/types/router/runtime/provider.d.ts +28 -11
  146. package/dist/types/router/runtime/types.d.ts +27 -5
  147. package/package.json +47 -27
  148. package/dist/cjs/exports/tanstack-router.js +0 -83
  149. package/dist/esm/exports/tanstack-router.mjs +0 -30
  150. package/dist/esm-node/exports/tanstack-router.mjs +0 -31
  151. package/dist/types/exports/tanstack-router.d.ts +0 -88
@@ -0,0 +1,82 @@
1
+ import "node:module";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useRuntimeContext } from "../core/context/runtime.mjs";
4
+ const DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY = '__modernDistributedSsrFragments';
5
+ const DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY = '__modernDistributedSsrFragmentRequest';
6
+ function distributedSsrFragmentKey(remote, expose) {
7
+ return `${remote}::${expose}`;
8
+ }
9
+ function getDistributedSsrFragmentContext(response) {
10
+ const locals = response?.locals;
11
+ if (!locals || 'object' != typeof locals) return;
12
+ const context = locals[DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY];
13
+ if (!context || 'object' != typeof context) return;
14
+ return context;
15
+ }
16
+ function useDistributedSsrFragmentProps({ boundaryId, expose }) {
17
+ const runtimeContext = useRuntimeContext();
18
+ const locals = runtimeContext.requestContext?.response?.locals;
19
+ const request = locals && 'object' == typeof locals ? locals[DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY] : void 0;
20
+ if (!request || 'object' != typeof request || request.boundaryId !== boundaryId || request.expose !== expose) throw new Error(`Distributed SSR fragment request contract mismatch for ${boundaryId} ${expose}.`);
21
+ const props = request.props;
22
+ if (!props || 'object' != typeof props || Array.isArray(props)) throw new Error(`Distributed SSR fragment request props must be an object for ${boundaryId} ${expose}.`);
23
+ return props;
24
+ }
25
+ function isThenable(value) {
26
+ return 'function' == typeof value.then;
27
+ }
28
+ function DistributedSsrBoundary({ children, expose, fallback, fragmentProps = {}, remote }) {
29
+ const runtimeContext = useRuntimeContext();
30
+ const key = distributedSsrFragmentKey(remote, expose);
31
+ const attributes = {
32
+ 'data-modern-distributed-ssr-boundary': key
33
+ };
34
+ if (runtimeContext.isBrowser) return /*#__PURE__*/ jsx("div", {
35
+ ...attributes,
36
+ children: children
37
+ });
38
+ const fragmentContext = getDistributedSsrFragmentContext(runtimeContext.requestContext?.response);
39
+ if (!fragmentContext) return /*#__PURE__*/ jsx("div", {
40
+ ...attributes,
41
+ children: children
42
+ });
43
+ const fragmentOrPromise = fragmentContext.resolve?.(remote, expose, fragmentProps) ?? fragmentContext.fragments?.[key];
44
+ if (fragmentOrPromise && isThenable(fragmentOrPromise)) throw fragmentOrPromise;
45
+ const fragment = fragmentOrPromise;
46
+ if (fragment?.status === 'ready') return /*#__PURE__*/ jsx("div", {
47
+ ...attributes,
48
+ "data-modern-distributed-ssr-build": fragment.buildMarker,
49
+ "data-modern-distributed-ssr-digest": fragment.digest,
50
+ "data-modern-distributed-ssr-status": "ready",
51
+ dangerouslySetInnerHTML: {
52
+ __html: fragment.html
53
+ }
54
+ });
55
+ return /*#__PURE__*/ jsx("div", {
56
+ ...attributes,
57
+ "data-modern-distributed-ssr-reason": fragment?.reason ?? 'missing',
58
+ "data-modern-distributed-ssr-status": "degraded",
59
+ children: fallback
60
+ });
61
+ }
62
+ function createDistributedSsrComponent({ createComponent, expose, fallback, remote }) {
63
+ let RemoteComponent;
64
+ function DeferredRemoteComponent(props) {
65
+ RemoteComponent ??= createComponent();
66
+ return /*#__PURE__*/ jsx(RemoteComponent, {
67
+ ...props
68
+ });
69
+ }
70
+ return function(props) {
71
+ return /*#__PURE__*/ jsx(DistributedSsrBoundary, {
72
+ expose: expose,
73
+ fallback: fallback,
74
+ fragmentProps: props,
75
+ remote: remote,
76
+ children: /*#__PURE__*/ jsx(DeferredRemoteComponent, {
77
+ ...props
78
+ })
79
+ });
80
+ };
81
+ }
82
+ export { DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY, DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY, DistributedSsrBoundary, createDistributedSsrComponent, distributedSsrFragmentKey, useDistributedSsrFragmentProps };
@@ -1,4 +1,9 @@
1
1
  import "node:module";
2
+ export * from "./consume-surface.mjs";
3
+ export * from "./distributed-ssr.mjs";
4
+ export * from "./last-known-good.mjs";
5
+ export * from "./manifest-recovery-runtime-plugin.mjs";
6
+ export * from "./surface-resolution-types.mjs";
2
7
  const MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT = 'modernjs:mf-runtime-fallback';
3
8
  const MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT = 'modernjs:mf-runtime-recovery';
4
9
  const DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT = '/_modern/contract-gates/runtime-fallback';
@@ -107,4 +112,5 @@ async function emitModuleFederationFallbackTelemetry(input, options = {}) {
107
112
  postStatus: response.status
108
113
  };
109
114
  }
115
+ export { DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY, useDistributedSsrFragmentProps } from "./distributed-ssr.mjs";
110
116
  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 };
@@ -0,0 +1,81 @@
1
+ import "node:module";
2
+ import { createDiscoveryError, deliveryUnitResolutionKey } from "./surface-resolution-types.mjs";
3
+ const LAST_KNOWN_GOOD_PROVIDER_NAME = 'last-known-good';
4
+ function createInMemoryLkgStorage() {
5
+ const map = new Map();
6
+ return {
7
+ read (key) {
8
+ return map.get(key);
9
+ },
10
+ write (key, record) {
11
+ map.set(key, record);
12
+ }
13
+ };
14
+ }
15
+ function markDegraded(resolved, reason) {
16
+ return {
17
+ ...resolved,
18
+ compatibility: {
19
+ ...resolved.compatibility,
20
+ status: 'degraded',
21
+ reason
22
+ }
23
+ };
24
+ }
25
+ function staleRecordResult(ref, env, ageMs, maxStaleMs) {
26
+ return {
27
+ ok: false,
28
+ error: createDiscoveryError('stale-record', ref, `Last-known-good record for surface is stale: age ${ageMs}ms exceeds maxStaleMs ${maxStaleMs}ms`, {
29
+ env,
30
+ ageMs,
31
+ maxStaleMs
32
+ })
33
+ };
34
+ }
35
+ function createLastKnownGoodProvider(options) {
36
+ const storage = options.storage ?? createInMemoryLkgStorage();
37
+ const now = options.now ?? (()=>Date.now());
38
+ const maxStaleMs = options.freshness?.maxStaleMs;
39
+ async function serveFromCache(ref, env, fallback) {
40
+ const key = deliveryUnitResolutionKey(ref.unitId, env);
41
+ const cached = await storage.read(key);
42
+ if (!cached) return fallback();
43
+ if (cached.major !== ref.major) return fallback();
44
+ if ('incompatible' === cached.resolved.compatibility.status) return fallback();
45
+ const ageMs = now() - cached.storedAt;
46
+ if (void 0 !== maxStaleMs && ageMs > maxStaleMs) return staleRecordResult(ref, env, ageMs, maxStaleMs);
47
+ return {
48
+ ok: true,
49
+ unit: markDegraded(cached.resolved, `served last-known-good record (age ${ageMs}ms) after provider failure`)
50
+ };
51
+ }
52
+ return {
53
+ name: LAST_KNOWN_GOOD_PROVIDER_NAME,
54
+ async resolve (ref, env) {
55
+ const key = deliveryUnitResolutionKey(ref.unitId, env);
56
+ let resolution;
57
+ try {
58
+ resolution = await options.provider.resolve(ref, env);
59
+ } catch (error) {
60
+ return serveFromCache(ref, env, ()=>({
61
+ ok: false,
62
+ error: createDiscoveryError('provider-unavailable', ref, error instanceof Error ? error.message : 'provider threw a non-error value', {
63
+ env,
64
+ provider: options.provider.name
65
+ })
66
+ }));
67
+ }
68
+ if (!resolution.ok) {
69
+ const failure = resolution;
70
+ return serveFromCache(ref, env, ()=>failure);
71
+ }
72
+ if ('incompatible' !== resolution.unit.compatibility.status) await storage.write(key, {
73
+ resolved: resolution.unit,
74
+ storedAt: now(),
75
+ major: ref.major
76
+ });
77
+ return resolution;
78
+ }
79
+ };
80
+ }
81
+ export { LAST_KNOWN_GOOD_PROVIDER_NAME, createInMemoryLkgStorage, createLastKnownGoodProvider };
@@ -0,0 +1,101 @@
1
+ import "node:module";
2
+ const DEFAULT_ATTEMPTS = 3;
3
+ const DEFAULT_RETRY_DELAY_MS = 100;
4
+ const DEFAULT_TIMEOUT_MS = 1000;
5
+ const MAX_ATTEMPTS = 5;
6
+ const MAX_RETRY_DELAY_MS = 1000;
7
+ const MAX_TIMEOUT_MS = 5000;
8
+ const RETRYABLE_HTTP_STATUSES = new Set([
9
+ 408,
10
+ 425,
11
+ 429,
12
+ 500,
13
+ 502,
14
+ 503,
15
+ 504
16
+ ]);
17
+ const NON_RETRYABLE_ERROR_PATTERNS = [
18
+ /RUNTIME-013/i,
19
+ /invalid manifest/i,
20
+ /manifest (?:schema|contract|version|identity)/i,
21
+ /(?:incompatible|mismatch).*(?:manifest|remote)/i
22
+ ];
23
+ const clampInteger = (value, fallback, minimum, maximum)=>{
24
+ if (void 0 === value || !Number.isFinite(value)) return fallback;
25
+ return Math.min(maximum, Math.max(minimum, Math.floor(value)));
26
+ };
27
+ const getErrorMessage = (error)=>{
28
+ if (error instanceof Error) return error.message;
29
+ return 'string' == typeof error ? error : '';
30
+ };
31
+ const getErrorStatus = (error)=>{
32
+ if ('object' == typeof error && null !== error && 'status' in error && 'number' == typeof error.status) return error.status;
33
+ };
34
+ const isRetryableError = (error)=>{
35
+ if (error instanceof SyntaxError) return false;
36
+ const message = getErrorMessage(error);
37
+ if (NON_RETRYABLE_ERROR_PATTERNS.some((pattern)=>pattern.test(message))) return false;
38
+ const status = getErrorStatus(error);
39
+ if (void 0 !== status) return RETRYABLE_HTTP_STATUSES.has(status);
40
+ if (error instanceof Error && [
41
+ 'AbortError',
42
+ 'TimeoutError'
43
+ ].includes(error.name)) return true;
44
+ return error instanceof TypeError || /(?:fetch failed|network|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN)/i.test(message);
45
+ };
46
+ const isHttpManifestUrl = (id)=>{
47
+ if (!id) return false;
48
+ try {
49
+ const url = new URL(id);
50
+ return ('http:' === url.protocol || 'https:' === url.protocol) && url.pathname.endsWith('.json');
51
+ } catch {
52
+ return false;
53
+ }
54
+ };
55
+ const defaultWait = (milliseconds)=>new Promise((resolve)=>{
56
+ setTimeout(resolve, milliseconds);
57
+ });
58
+ const fetchWithTimeout = async (fetchImpl, url, timeoutMs)=>{
59
+ const controller = new AbortController();
60
+ const timeout = setTimeout(()=>controller.abort(), timeoutMs);
61
+ try {
62
+ return await fetchImpl(url, {
63
+ signal: controller.signal
64
+ });
65
+ } finally{
66
+ clearTimeout(timeout);
67
+ }
68
+ };
69
+ const createModuleFederationManifestRecoveryPlugin = (options = {})=>{
70
+ const attempts = clampInteger(options.attempts, DEFAULT_ATTEMPTS, 1, MAX_ATTEMPTS);
71
+ const retryDelayMs = clampInteger(options.retryDelayMs, DEFAULT_RETRY_DELAY_MS, 0, MAX_RETRY_DELAY_MS);
72
+ const timeoutMs = clampInteger(options.timeoutMs, DEFAULT_TIMEOUT_MS, 1, MAX_TIMEOUT_MS);
73
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
74
+ const waitImpl = options.waitImpl ?? defaultWait;
75
+ return {
76
+ name: 'modern-js-manifest-recovery-plugin',
77
+ async errorLoadRemote (args) {
78
+ if ('afterResolve' !== args.lifecycle || !isHttpManifestUrl(args.id) || !isRetryableError(args.error) || 'function' != typeof fetchImpl) return;
79
+ for(let attempt = 0; attempt < attempts; attempt++){
80
+ if (attempt > 0 && retryDelayMs > 0) await waitImpl(retryDelayMs);
81
+ try {
82
+ const response = await fetchWithTimeout(fetchImpl, args.id, timeoutMs);
83
+ if (!response.ok) {
84
+ if (!RETRYABLE_HTTP_STATUSES.has(response.status) || attempt === attempts - 1) return;
85
+ continue;
86
+ }
87
+ try {
88
+ return await response.json();
89
+ } catch {
90
+ break;
91
+ }
92
+ } catch (error) {
93
+ if (!isRetryableError(error) || attempt === attempts - 1) break;
94
+ }
95
+ }
96
+ }
97
+ };
98
+ };
99
+ const manifest_recovery_runtime_plugin = createModuleFederationManifestRecoveryPlugin;
100
+ export default manifest_recovery_runtime_plugin;
101
+ export { createModuleFederationManifestRecoveryPlugin };
@@ -0,0 +1,9 @@
1
+ import "node:module";
2
+ import { createDiscoveryError, formatSurfaceRef, parseSurfaceRef, validateSurfaceRef } from "@modern-js/utils/universal";
3
+ function surfaceResolutionKey(ref, env) {
4
+ return `${env}::${formatSurfaceRef(ref)}`;
5
+ }
6
+ function deliveryUnitResolutionKey(unitId, env) {
7
+ return `${env}::${unitId}`;
8
+ }
9
+ export { createDiscoveryError, deliveryUnitResolutionKey, formatSurfaceRef, parseSurfaceRef, surfaceResolutionKey, validateSurfaceRef };
@@ -7,7 +7,7 @@ import { resolveSSRMode } from "../../../cli/ssr/mode.mjs";
7
7
  import { FILE_SYSTEM_ROUTES_FILE_NAME } from "../constants.mjs";
8
8
  import { walk } from "./nestedRoutes.mjs";
9
9
  import { getServerCombinedModuleFile, getServerLoadersFile } from "./utils.mjs";
10
- import * as __rspack_external__templates_mjs_4da4c6c8 from "./templates.mjs";
10
+ import * as __rspack_external__templates_mjs_ab577925 from "./templates.mjs";
11
11
  async function generateRoutesForEntry(entrypoint, appContext) {
12
12
  const routes = [];
13
13
  if (entrypoint.nestedRoutesEntry) {
@@ -90,7 +90,7 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
90
90
  }
91
91
  const { code } = await hooks.onBeforeGenerateRoutes.call({
92
92
  entrypoint,
93
- code: await __rspack_external__templates_mjs_4da4c6c8.fileSystemRoutes({
93
+ code: await __rspack_external__templates_mjs_ab577925.fileSystemRoutes({
94
94
  metaName,
95
95
  routes: routes,
96
96
  ssrMode: isUseRsc(config) ? 'stream' : ssrMode,
@@ -107,12 +107,12 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
107
107
  const routesServerFile = getServerLoadersFile(internalDirectory, entryName);
108
108
  const filtedRoutesForServer = filterRoutesForServer(routes);
109
109
  const routesForServerLoaderMatches = filterRoutesLoader(routes);
110
- const code = __rspack_external__templates_mjs_4da4c6c8.routesForServer({
110
+ const code = __rspack_external__templates_mjs_ab577925.routesForServer({
111
111
  routesForServerLoaderMatches
112
112
  });
113
113
  await fs.ensureFile(routesServerFile);
114
114
  await fs.writeFile(routesServerFile, code);
115
- const serverRoutesCode = await __rspack_external__templates_mjs_4da4c6c8.fileSystemRoutes({
115
+ const serverRoutesCode = await __rspack_external__templates_mjs_ab577925.fileSystemRoutes({
116
116
  metaName,
117
117
  routes: filtedRoutesForServer,
118
118
  ssrMode,
@@ -126,7 +126,7 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
126
126
  });
127
127
  await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, 'utf8');
128
128
  }
129
- const serverLoaderCombined = __rspack_external__templates_mjs_4da4c6c8.ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext);
129
+ const serverLoaderCombined = __rspack_external__templates_mjs_ab577925.ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext);
130
130
  if (serverLoaderCombined) {
131
131
  const serverLoaderFile = getServerCombinedModuleFile(internalDirectory, entryName);
132
132
  await fs.outputFile(serverLoaderFile, serverLoaderCombined);
@@ -83,6 +83,7 @@ const walk = async (options)=>{
83
83
  let pageLoaderFile = '';
84
84
  let pageRoute = null;
85
85
  let pageConfigFile = '';
86
+ let pageSearchFile = '';
86
87
  let pageClientData = '';
87
88
  let pageData = '';
88
89
  let pageAction = '';
@@ -129,12 +130,14 @@ const walk = async (options)=>{
129
130
  if (await hasAction(itemPath)) pageAction = itemPathWithAlias;
130
131
  }
131
132
  if (itemWithoutExt === NESTED_ROUTE.PAGE_CONFIG_FILE) pageConfigFile = itemPathWithAlias;
133
+ if (itemWithoutExt === NESTED_ROUTE.PAGE_SEARCH_FILE) pageSearchFile = itemPathWithAlias;
132
134
  if (itemWithoutExt === NESTED_ROUTE.PAGE_FILE) {
133
135
  pageRoute = createIndexRoute({
134
136
  _component: itemPathWithAlias
135
137
  }, rootDir, itemPath, entryName, isMainEntry);
136
138
  if (pageLoaderFile) pageRoute.loader = pageLoaderFile;
137
139
  if (pageConfigFile) pageRoute.config = pageConfigFile;
140
+ if (pageSearchFile) pageRoute.validateSearch = pageSearchFile;
138
141
  if (pageData) pageRoute.data = pageData;
139
142
  if (pageClientData) pageRoute.clientData = pageClientData;
140
143
  if (pageAction) pageRoute.action = pageAction;
@@ -184,7 +184,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
184
184
  component = `component_${components.length - 1}`;
185
185
  }
186
186
  const isClientComponent = 'nested' === route.type && Boolean(route._component) && Boolean(srcDirectory) && Boolean(internalSrcAlias) && await hasUseClientDirective(route._component, srcDirectory, internalSrcAlias);
187
- const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent;
187
+ const shouldHydrateRscRoute = isRscClientBundle && !isClientComponent && !route.loader && !route.data;
188
+ const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent || shouldHydrateRscRoute;
188
189
  const finalRoute = {
189
190
  ...route,
190
191
  loading,
@@ -287,7 +288,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
287
288
  ${importLazyCode}
288
289
  ${!isRscClientBundle ? importComponentsCode : ''}
289
290
  ${importRuntimeRouterCode}
290
- ${!isRscClientBundle ? rootLayoutCode : ''}
291
+ ${rootLayoutCode}
291
292
  ${importLoadingCode}
292
293
  ${importErrorComponentsCode}
293
294
  ${importLoadersCode}
@@ -19,6 +19,7 @@ const NESTED_ROUTE = {
19
19
  PAGE_FILE: 'page',
20
20
  PAGE_CONFIG_FILE: 'page.config',
21
21
  PAGE_LOADER_FILE: 'page.loader',
22
+ PAGE_SEARCH_FILE: 'page.search',
22
23
  PAGE_DATA_FILE: 'page.data',
23
24
  PAGE_CLIENT_LOADER: 'page.data.client',
24
25
  SPLATE_FILE: '$',
@@ -4,7 +4,7 @@ import { cloneDeep } from "@modern-js/utils/lodash";
4
4
  import path from "path";
5
5
  import { isPageComponentFile } from "./code/utils.mjs";
6
6
  import { modifyEntrypoints } from "./entry.mjs";
7
- import * as __rspack_external__code_templates_mjs_5e908598 from "./code/templates.mjs";
7
+ import * as __rspack_external__code_templates_mjs_f6c22489 from "./code/templates.mjs";
8
8
  const DEFAULT_ENTRYPOINTS_KEY = '__default_router_entries__';
9
9
  const originEntrypointsByKey = new Map();
10
10
  async function handleModifyEntrypoints(entrypoints, routesDir, options = {}) {
@@ -26,7 +26,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
26
26
  if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
27
27
  const route = appContext.serverRoutes.find((r)=>r.entryName === entrypoint.entryName);
28
28
  const basename = route?.urlPath || '/';
29
- generatorRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_5e908598.runtimeGlobalContext({
29
+ generatorRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_f6c22489.runtimeGlobalContext({
30
30
  entryName: entrypoint.entryName,
31
31
  metaName: appContext.metaName,
32
32
  srcDirectory: appContext.srcDirectory,
@@ -36,7 +36,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
36
36
  rscType: enableRsc ? 'client' : void 0,
37
37
  basename
38
38
  }));
39
- if (enableRsc) generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_5e908598.runtimeGlobalContext({
39
+ if (enableRsc) generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_f6c22489.runtimeGlobalContext({
40
40
  entryName: entrypoint.entryName,
41
41
  metaName: appContext.metaName,
42
42
  srcDirectory: appContext.srcDirectory,
@@ -2,6 +2,7 @@ import "node:module";
2
2
  import node_path from "node:path";
3
3
  import { setTimeout as promises_setTimeout } from "node:timers/promises";
4
4
  import { fs } from "@modern-js/utils";
5
+ import { cloneDeep } from "@modern-js/utils/lodash";
5
6
  const lockPollIntervalMs = 25;
6
7
  const staleLockAgeMs = 120000;
7
8
  const pendingUpdates = new Map();
@@ -44,6 +45,7 @@ async function writeJSONAtomically(filePath, value) {
44
45
  }
45
46
  async function updateNestedRoutesSpec(specPath, nextRoutes) {
46
47
  const resolvedSpecPath = node_path.resolve(specPath);
48
+ const nextRoutesSnapshot = cloneDeep(nextRoutes);
47
49
  const previousUpdate = pendingUpdates.get(resolvedSpecPath) ?? Promise.resolve();
48
50
  const currentUpdate = previousUpdate.catch(()=>void 0).then(async ()=>{
49
51
  const releaseLock = await acquireSpecLock(resolvedSpecPath);
@@ -51,7 +53,7 @@ async function updateNestedRoutesSpec(specPath, nextRoutes) {
51
53
  const existingRoutes = await fs.pathExists(resolvedSpecPath) ? await fs.readJSON(resolvedSpecPath) : {};
52
54
  await writeJSONAtomically(resolvedSpecPath, {
53
55
  ...existingRoutes,
54
- ...nextRoutes
56
+ ...nextRoutesSnapshot
55
57
  });
56
58
  } finally{
57
59
  await releaseLock();
@@ -1,9 +1,10 @@
1
1
  import "node:module";
2
2
  import { createSyncHook } from "@modern-js/plugin";
3
- const modifyRoutes = createSyncHook();
4
- const onBeforeCreateRoutes = createSyncHook();
5
- const onBeforeCreateRouter = createSyncHook();
6
- const onAfterCreateRouter = createSyncHook();
7
- const onBeforeHydrateRouter = createSyncHook();
8
- const onAfterHydrateRouter = createSyncHook();
3
+ const createRouterSyncHook = ()=>createSyncHook();
4
+ const modifyRoutes = createRouterSyncHook();
5
+ const onBeforeCreateRoutes = createRouterSyncHook();
6
+ const onBeforeCreateRouter = createRouterSyncHook();
7
+ const onAfterCreateRouter = createRouterSyncHook();
8
+ const onBeforeHydrateRouter = createRouterSyncHook();
9
+ const onAfterHydrateRouter = createRouterSyncHook();
9
10
  export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter };
@@ -1,27 +1,35 @@
1
1
  import "node:module";
2
2
  import { merge } from "@modern-js/runtime-utils/merge";
3
3
  import { modifyRoutes, routerPlugin } from "./plugin.mjs";
4
- import { registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
4
+ import { createRouterProviderRealm, registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
5
5
  registerRouterProvider('react-router', routerPlugin, {
6
6
  isDefault: true
7
7
  });
8
- const internal_routerPlugin = (userConfig = {})=>({
9
- name: '@modern-js/plugin-router',
10
- registryHooks: routerProviderRegistryHooks,
11
- setup: (api)=>{
12
- const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
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);
22
- }
23
- });
8
+ const createRouterPlugin = (localProviders = [])=>{
9
+ const providerRealm = createRouterProviderRealm([
10
+ {
11
+ name: 'react-router',
12
+ factory: routerPlugin,
13
+ isDefault: true
14
+ },
15
+ ...localProviders
16
+ ]);
17
+ return (userConfig = {})=>({
18
+ name: '@modern-js/plugin-router',
19
+ registryHooks: routerProviderRegistryHooks,
20
+ setup: (api)=>{
21
+ const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
22
+ const pluginFactory = resolveRouterProvider(mergedConfig.framework, {
23
+ realm: providerRealm
24
+ });
25
+ const providerPlugin = pluginFactory(userConfig);
26
+ reportUnsupportedProviderRegistryHooks(providerPlugin);
27
+ providerPlugin.setup?.(api);
28
+ }
29
+ });
30
+ };
31
+ const internal_routerPlugin = createRouterPlugin();
24
32
  const internal = internal_routerPlugin;
25
33
  export { renderRoutes } from "./utils.mjs";
26
34
  export default internal;
27
- export { internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
35
+ export { createRouterPlugin, createRouterProviderRealm, internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
@@ -65,10 +65,10 @@ const routerPlugin = (userConfig = {})=>({
65
65
  };
66
66
  let cachedRouter = null;
67
67
  const RouterWrapper = (props)=>{
68
- const routerResult = useRouterCreation({
68
+ const routerResult = useRouterCreation(process.env.MODERN_ENABLE_RSC ? {
69
69
  ...props,
70
70
  rscPayload: props?.rscPayload
71
- }, {
71
+ } : props, {
72
72
  api: api,
73
73
  createRoutes,
74
74
  supportHtml5History,
@@ -122,16 +122,15 @@ function useRouterCreation(props, options) {
122
122
  const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
123
123
  const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
124
124
  const { unstable_getBlockNavState: getBlockNavState } = runtimeContext;
125
- const rscPayload = props?.rscPayload ? safeUse(props.rscPayload) : null;
126
- let hydrationData = window._ROUTER_DATA || rscPayload;
125
+ const rscPayload = process.env.MODERN_ENABLE_RSC && props?.rscPayload ? safeUse(props.rscPayload) : null;
126
+ let hydrationData = process.env.MODERN_ENABLE_RSC ? window._ROUTER_DATA || rscPayload : window._ROUTER_DATA;
127
127
  return (0, __rspack_external_react.useMemo)(()=>{
128
128
  if (hydrationData?.errors) hydrationData = {
129
129
  ...hydrationData,
130
130
  errors: deserializeErrors(hydrationData.errors)
131
131
  };
132
- const isRscClient = getGlobalIsRscClient();
133
132
  let routes = null;
134
- routes = isRscClient ? createRoutes ? createRoutes() : createRouteObjectsFromConfig({
133
+ routes = process.env.MODERN_ENABLE_RSC && getGlobalIsRscClient() ? createRoutes ? createRoutes() : createRouteObjectsFromConfig({
135
134
  routesConfig: finalRouteConfig
136
135
  }) : createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
137
136
  routesConfig: finalRouteConfig,
@@ -139,7 +138,7 @@ function useRouterCreation(props, options) {
139
138
  }));
140
139
  if (!routes) routes = [];
141
140
  const hooks = api.getHooks();
142
- if (rscPayload) try {
141
+ if (process.env.MODERN_ENABLE_RSC && rscPayload) try {
143
142
  const router = createClientRouterFromPayload(rscPayload, routes, _basename);
144
143
  return {
145
144
  router,