@bleedingdev/modern-js-runtime 3.5.0-ultramodern.6 → 3.5.0-ultramodern.75

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 (145) hide show
  1. package/dist/cjs/boundary-debugger/index.js +13 -3
  2. package/dist/cjs/cli/registry.js +18 -0
  3. package/dist/cjs/cli/ssr/index.js +3 -2
  4. package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +8 -4
  5. package/dist/cjs/core/browser/hydrate.js +16 -2
  6. package/dist/cjs/core/browser/index.js +15 -3
  7. package/dist/cjs/core/context/index.js +3 -0
  8. package/dist/cjs/core/context/public.js +49 -0
  9. package/dist/cjs/core/context/runtime.js +6 -8
  10. package/dist/cjs/core/react/wrapper.js +57 -0
  11. package/dist/cjs/core/server/federatedCss.js +7 -3
  12. package/dist/cjs/core/server/requestHandler.js +15 -45
  13. package/dist/cjs/core/server/requestResponse.js +83 -0
  14. package/dist/cjs/core/server/routerCleanup.js +16 -6
  15. package/dist/cjs/core/server/scriptOrder.js +13 -10
  16. package/dist/cjs/core/server/stream/afterTemplate.js +9 -5
  17. package/dist/cjs/core/server/stream/template.js +3 -3
  18. package/dist/cjs/core/server/string/loadable.js +3 -11
  19. package/dist/cjs/index.js +7 -6
  20. package/dist/cjs/module-federation/consume-surface.js +199 -0
  21. package/dist/cjs/module-federation/distributed-ssr.js +134 -0
  22. package/dist/cjs/module-federation/index.js +258 -120
  23. package/dist/cjs/module-federation/last-known-good.js +124 -0
  24. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +140 -0
  25. package/dist/cjs/module-federation/surface-resolution-types.js +61 -0
  26. package/dist/cjs/router/cli/code/nestedRoutes.js +3 -0
  27. package/dist/cjs/router/cli/code/templates.js +3 -2
  28. package/dist/cjs/router/cli/constants.js +1 -0
  29. package/dist/cjs/router/cli/nestedRoutesSpec.js +3 -1
  30. package/dist/cjs/router/runtime/hooks.js +7 -6
  31. package/dist/cjs/router/runtime/internal.js +30 -16
  32. package/dist/cjs/router/runtime/plugin.js +6 -7
  33. package/dist/cjs/router/runtime/provider.js +58 -12
  34. package/dist/esm/boundary-debugger/index.mjs +13 -3
  35. package/dist/esm/cli/code.mjs +12 -12
  36. package/dist/esm/cli/registry.mjs +0 -0
  37. package/dist/esm/cli/ssr/index.mjs +3 -2
  38. package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +8 -4
  39. package/dist/esm/core/browser/hydrate.mjs +15 -4
  40. package/dist/esm/core/browser/index.mjs +11 -5
  41. package/dist/esm/core/context/index.mjs +1 -1
  42. package/dist/esm/core/context/public.mjs +5 -0
  43. package/dist/esm/core/context/runtime.mjs +4 -6
  44. package/dist/esm/core/react/wrapper.mjs +58 -1
  45. package/dist/esm/core/server/federatedCss.mjs +7 -3
  46. package/dist/esm/core/server/requestHandler.mjs +15 -45
  47. package/dist/esm/core/server/requestResponse.mjs +39 -0
  48. package/dist/esm/core/server/routerCleanup.mjs +11 -4
  49. package/dist/esm/core/server/scriptOrder.mjs +11 -8
  50. package/dist/esm/core/server/stream/afterTemplate.mjs +10 -6
  51. package/dist/esm/core/server/stream/template.mjs +3 -3
  52. package/dist/esm/core/server/string/loadable.mjs +3 -8
  53. package/dist/esm/exports/loadable.mjs +3 -3
  54. package/dist/esm/index.mjs +2 -1
  55. package/dist/esm/module-federation/consume-surface.mjs +158 -0
  56. package/dist/esm/module-federation/distributed-ssr.mjs +81 -0
  57. package/dist/esm/module-federation/index.mjs +6 -0
  58. package/dist/esm/module-federation/last-known-good.mjs +80 -0
  59. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +100 -0
  60. package/dist/esm/module-federation/surface-resolution-types.mjs +8 -0
  61. package/dist/esm/router/cli/code/index.mjs +5 -5
  62. package/dist/esm/router/cli/code/nestedRoutes.mjs +3 -0
  63. package/dist/esm/router/cli/code/templates.mjs +3 -2
  64. package/dist/esm/router/cli/constants.mjs +1 -0
  65. package/dist/esm/router/cli/handler.mjs +3 -3
  66. package/dist/esm/router/cli/nestedRoutesSpec.mjs +3 -1
  67. package/dist/esm/router/runtime/hooks.mjs +7 -6
  68. package/dist/esm/router/runtime/internal.mjs +26 -18
  69. package/dist/esm/router/runtime/plugin.mjs +6 -7
  70. package/dist/esm/router/runtime/provider.mjs +56 -13
  71. package/dist/esm-node/boundary-debugger/index.mjs +13 -3
  72. package/dist/esm-node/cli/code.mjs +12 -12
  73. package/dist/esm-node/cli/registry.mjs +1 -0
  74. package/dist/esm-node/cli/ssr/index.mjs +3 -2
  75. package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +8 -4
  76. package/dist/esm-node/core/browser/hydrate.mjs +15 -4
  77. package/dist/esm-node/core/browser/index.mjs +11 -5
  78. package/dist/esm-node/core/context/index.mjs +1 -1
  79. package/dist/esm-node/core/context/public.mjs +6 -0
  80. package/dist/esm-node/core/context/runtime.mjs +4 -6
  81. package/dist/esm-node/core/react/wrapper.mjs +58 -1
  82. package/dist/esm-node/core/server/federatedCss.mjs +7 -3
  83. package/dist/esm-node/core/server/requestHandler.mjs +15 -45
  84. package/dist/esm-node/core/server/requestResponse.mjs +40 -0
  85. package/dist/esm-node/core/server/routerCleanup.mjs +11 -4
  86. package/dist/esm-node/core/server/scriptOrder.mjs +11 -8
  87. package/dist/esm-node/core/server/stream/afterTemplate.mjs +10 -6
  88. package/dist/esm-node/core/server/stream/template.mjs +3 -3
  89. package/dist/esm-node/core/server/string/loadable.mjs +3 -8
  90. package/dist/esm-node/exports/loadable.mjs +3 -3
  91. package/dist/esm-node/index.mjs +2 -1
  92. package/dist/esm-node/module-federation/consume-surface.mjs +159 -0
  93. package/dist/esm-node/module-federation/distributed-ssr.mjs +82 -0
  94. package/dist/esm-node/module-federation/index.mjs +6 -0
  95. package/dist/esm-node/module-federation/last-known-good.mjs +81 -0
  96. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +101 -0
  97. package/dist/esm-node/module-federation/surface-resolution-types.mjs +9 -0
  98. package/dist/esm-node/router/cli/code/index.mjs +5 -5
  99. package/dist/esm-node/router/cli/code/nestedRoutes.mjs +3 -0
  100. package/dist/esm-node/router/cli/code/templates.mjs +3 -2
  101. package/dist/esm-node/router/cli/constants.mjs +1 -0
  102. package/dist/esm-node/router/cli/handler.mjs +3 -3
  103. package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +3 -1
  104. package/dist/esm-node/router/runtime/hooks.mjs +7 -6
  105. package/dist/esm-node/router/runtime/internal.mjs +26 -18
  106. package/dist/esm-node/router/runtime/plugin.mjs +6 -7
  107. package/dist/esm-node/router/runtime/provider.mjs +56 -13
  108. package/dist/types/boundary-debugger/index.d.ts +1 -1
  109. package/dist/types/cli/registry.d.ts +2 -0
  110. package/dist/types/common.d.ts +8 -1
  111. package/dist/types/core/browser/hydrate.d.ts +2 -1
  112. package/dist/types/core/browser/index.d.ts +4 -0
  113. package/dist/types/core/context/index.d.ts +26 -10
  114. package/dist/types/core/context/monitors/default.d.ts +10 -2
  115. package/dist/types/core/context/monitors/index.d.ts +1 -1
  116. package/dist/types/core/context/monitors/index.server.d.ts +2 -2
  117. package/dist/types/core/context/public.d.ts +27 -0
  118. package/dist/types/core/context/runtime.d.ts +12 -22
  119. package/dist/types/core/react/index.d.ts +1 -1
  120. package/dist/types/core/server/requestResponse.d.ts +15 -0
  121. package/dist/types/core/server/routerCleanup.d.ts +2 -1
  122. package/dist/types/core/server/scriptOrder.d.ts +1 -1
  123. package/dist/types/core/server/stream/shared.d.ts +2 -2
  124. package/dist/types/core/server/string/loadable.d.ts +0 -2
  125. package/dist/types/exports/head.d.ts +1 -1
  126. package/dist/types/index.d.ts +5 -5
  127. package/dist/types/internal.d.ts +0 -1
  128. package/dist/types/module-federation/consume-surface.d.ts +104 -0
  129. package/dist/types/module-federation/distributed-ssr.d.ts +61 -0
  130. package/dist/types/module-federation/index.d.ts +6 -0
  131. package/dist/types/module-federation/last-known-good.d.ts +72 -0
  132. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +25 -0
  133. package/dist/types/module-federation/surface-resolution-types.d.ts +23 -0
  134. package/dist/types/router/cli/constants.d.ts +1 -0
  135. package/dist/types/router/runtime/hooks.d.ts +10 -6
  136. package/dist/types/router/runtime/internal.d.ts +13 -3
  137. package/dist/types/router/runtime/plugin.d.ts +1 -1
  138. package/dist/types/router/runtime/plugin.node.d.ts +1 -1
  139. package/dist/types/router/runtime/provider.d.ts +28 -11
  140. package/dist/types/router/runtime/types.d.ts +27 -5
  141. package/package.json +46 -27
  142. package/dist/cjs/exports/tanstack-router.js +0 -83
  143. package/dist/esm/exports/tanstack-router.mjs +0 -30
  144. package/dist/esm-node/exports/tanstack-router.mjs +0 -31
  145. package/dist/types/exports/tanstack-router.d.ts +0 -88
@@ -1,6 +1,6 @@
1
1
  import { ChunkExtractor } from "@loadable/server";
2
2
  import { createFederatedCssLinks } from "../federatedCss.mjs";
3
- import { getMatchedRouteAssets, orderHydrationScriptChunks } from "../scriptOrder.mjs";
3
+ import { getMatchedRouteChunks, orderHydrationScriptChunks } from "../scriptOrder.mjs";
4
4
  import { attributesToString, checkIsNode, hasStylesheetLink } from "../utils.mjs";
5
5
  const extname = (uri)=>{
6
6
  if ('string' != typeof uri || !uri.includes('.')) return '';
@@ -28,11 +28,6 @@ const readAsset = async (chunk)=>{
28
28
  return fs.readFile(filepath, 'utf-8');
29
29
  };
30
30
  class LoadableCollector {
31
- getMatchedRouteChunks() {
32
- const { routeManifest, runtimeContext } = this.options;
33
- if (!routeManifest) return [];
34
- return getMatchedRouteAssets(runtimeContext, routeManifest).map(routeAssetToChunk);
35
- }
36
31
  collect(comopnent) {
37
32
  const { stats, entryName } = this.options;
38
33
  if (!stats) return comopnent;
@@ -54,7 +49,7 @@ class LoadableCollector {
54
49
  ]));
55
50
  } catch (e) {}
56
51
  const collectedChunks = extractor ? extractor.getChunkAssets(extractor.chunks) : [];
57
- const matchedRouteChunks = this.getMatchedRouteChunks();
52
+ const matchedRouteChunks = getMatchedRouteChunks(options.runtimeContext, options.routeManifest, routeAssetToChunk);
58
53
  const orderedScriptChunks = orderHydrationScriptChunks({
59
54
  asyncEntryChunks: asyncChunks,
60
55
  collectedChunks,
@@ -132,4 +127,4 @@ class LoadableCollector {
132
127
  this.options = options;
133
128
  }
134
129
  }
135
- export { LoadableCollector, orderHydrationScriptChunks };
130
+ export { LoadableCollector };
@@ -1,4 +1,4 @@
1
- import * as __rspack_external__loadable_component_0aaae075 from "@loadable/component";
1
+ import * as __rspack_external__loadable_component_ee3b4254 from "@loadable/component";
2
2
  export * from "@loadable/component";
3
3
  function asLoadableNamespace(value) {
4
4
  return 'object' == typeof value && null !== value ? value : {};
@@ -15,8 +15,8 @@ function resolveLoadable(module) {
15
15
  if ('function' != typeof loadable) throw new TypeError('Modern.js runtime loadable export must resolve to a function');
16
16
  return loadable;
17
17
  }
18
- const loadable_loadable = resolveLoadable(__rspack_external__loadable_component_0aaae075);
19
- const loadableNamespace = asLoadableNamespace(__rspack_external__loadable_component_0aaae075);
18
+ const loadable_loadable = resolveLoadable(__rspack_external__loadable_component_ee3b4254);
19
+ const loadableNamespace = asLoadableNamespace(__rspack_external__loadable_component_ee3b4254);
20
20
  const loadableDefaultNamespace = asLoadableNamespace(loadableNamespace.default);
21
21
  const callableLoadableNamespace = asLoadableNamespace(loadable_loadable);
22
22
  const lazy = loadableNamespace.lazy ?? loadableDefaultNamespace.lazy ?? callableLoadableNamespace.lazy;
@@ -1,5 +1,6 @@
1
1
  export { isBrowser } from "./common.mjs";
2
- export { RuntimeContext, defineRuntimeConfig, useRuntimeContext } from "./core/index.mjs";
2
+ export { defineRuntimeConfig } from "./core/config.mjs";
3
3
  export { getMonitors } from "./core/context/monitors/index.mjs";
4
+ export { RuntimeContext, useRuntimeContext } from "./core/context/public.mjs";
4
5
  export { getRequest } from "./core/context/request/index.mjs";
5
6
  export { redirect, setHeaders, setStatus } from "./core/context/response/index.mjs";
@@ -0,0 +1,158 @@
1
+ import { classifyModuleFederationFallback, createModuleFederationFallbackTelemetry, emitModuleFederationFallbackTelemetry } from "./index.mjs";
2
+ import { createDiscoveryError, formatSurfaceRef, parseSurfaceRef, validateSurfaceRef } from "./surface-resolution-types.mjs";
3
+ function classifyDiscoveryError(code) {
4
+ switch(code){
5
+ case 'major-not-published':
6
+ case 'stale-record':
7
+ return 'version-skew';
8
+ case 'identity-mismatch':
9
+ return 'contract';
10
+ case 'unknown-unit':
11
+ case 'unknown-surface':
12
+ case 'provider-unavailable':
13
+ return 'remote-unavailable';
14
+ default:
15
+ return 'remote-unavailable';
16
+ }
17
+ }
18
+ function toRemoteString(ref) {
19
+ return void 0 === validateSurfaceRef(ref) ? formatSurfaceRef(ref) : `${ref.unitId}#${ref.surfaceId}`;
20
+ }
21
+ async function reportFailure(options, ref, base) {
22
+ const remote = toRemoteString(ref);
23
+ const telemetry = createModuleFederationFallbackTelemetry({
24
+ appName: options.appName,
25
+ classification: base.classification,
26
+ error: base.error ?? base.discoveryError,
27
+ metadata: {
28
+ env: options.env,
29
+ surfaceRef: remote,
30
+ ...base.discoveryError ? {
31
+ discoveryErrorCode: base.discoveryError.code
32
+ } : {},
33
+ ...base.resolved ? {
34
+ buildMarker: base.resolved.buildMarker
35
+ } : {}
36
+ },
37
+ phase: base.phase,
38
+ remote,
39
+ status: 'degraded'
40
+ });
41
+ try {
42
+ await emitModuleFederationFallbackTelemetry({
43
+ appName: options.appName,
44
+ classification: base.classification,
45
+ error: base.error ?? base.discoveryError,
46
+ metadata: telemetry.metadata,
47
+ phase: base.phase,
48
+ remote,
49
+ status: 'degraded'
50
+ }, options.telemetry ?? {});
51
+ } catch {}
52
+ const failure = {
53
+ ref,
54
+ env: options.env,
55
+ phase: base.phase,
56
+ classification: base.classification,
57
+ telemetry
58
+ };
59
+ if (base.discoveryError) failure.discoveryError = base.discoveryError;
60
+ if (void 0 !== base.error) failure.error = base.error;
61
+ if (base.resolved) failure.resolved = base.resolved;
62
+ const critical = (options.classification ?? 'critical') === 'critical';
63
+ const reason = base.discoveryError ?? (void 0 !== base.error ? base.error : createDiscoveryError('identity-mismatch', remote, `resolved record for "${remote}" is incompatible`, {
64
+ env: options.env
65
+ }));
66
+ let degradedValue;
67
+ try {
68
+ degradedValue = await options.degraded(failure);
69
+ } catch (handlerError) {
70
+ try {
71
+ await emitModuleFederationFallbackTelemetry({
72
+ appName: options.appName,
73
+ classification: base.classification,
74
+ error: handlerError,
75
+ metadata: {
76
+ ...telemetry.metadata,
77
+ degradedHandlerFailed: true
78
+ },
79
+ phase: base.phase,
80
+ remote,
81
+ status: 'failed'
82
+ }, options.telemetry ?? {});
83
+ } catch {}
84
+ if (critical) throw reason;
85
+ return;
86
+ }
87
+ if (critical) throw reason;
88
+ return degradedValue;
89
+ }
90
+ async function consumeSurface(options) {
91
+ let ref;
92
+ if ('string' == typeof options.ref) {
93
+ const parsed = parseSurfaceRef(options.ref);
94
+ if (!parsed.ok) {
95
+ const hashIndex = options.ref.indexOf('#');
96
+ const echoed = -1 === hashIndex ? {
97
+ unitId: options.ref,
98
+ surfaceId: ''
99
+ } : {
100
+ unitId: options.ref.slice(0, hashIndex),
101
+ surfaceId: options.ref.slice(hashIndex + 1)
102
+ };
103
+ return reportFailure(options, echoed, {
104
+ phase: 'discovery',
105
+ classification: 'remote-unavailable',
106
+ discoveryError: createDiscoveryError('unknown-surface', options.ref, `SurfaceRef "${options.ref}" is not a valid canonical reference (${parsed.error.code}).`, {
107
+ parseError: parsed.error,
108
+ env: options.env
109
+ })
110
+ });
111
+ }
112
+ ref = parsed.ref;
113
+ } else ref = options.ref;
114
+ let resolution;
115
+ try {
116
+ resolution = await options.provider.resolve(ref, options.env);
117
+ } catch (error) {
118
+ return reportFailure(options, ref, {
119
+ phase: 'discovery',
120
+ classification: classifyModuleFederationFallback(error),
121
+ error
122
+ });
123
+ }
124
+ if (!resolution.ok) return reportFailure(options, ref, {
125
+ phase: 'discovery',
126
+ classification: classifyDiscoveryError(resolution.error.code),
127
+ discoveryError: resolution.error
128
+ });
129
+ const resolved = resolution.unit;
130
+ if ('incompatible' === resolved.compatibility.status) return reportFailure(options, ref, {
131
+ phase: 'discovery',
132
+ classification: 'contract',
133
+ resolved
134
+ });
135
+ try {
136
+ return await options.load({
137
+ resolved,
138
+ ref,
139
+ env: options.env
140
+ });
141
+ } catch (error) {
142
+ return reportFailure(options, ref, {
143
+ phase: 'load',
144
+ classification: classifyModuleFederationFallback(error),
145
+ error,
146
+ resolved
147
+ });
148
+ }
149
+ }
150
+ function createSurfaceConsumer(base) {
151
+ return function(options) {
152
+ return consumeSurface({
153
+ ...base,
154
+ ...options
155
+ });
156
+ };
157
+ }
158
+ export { consumeSurface, createSurfaceConsumer };
@@ -0,0 +1,81 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useRuntimeContext } from "../core/context/runtime.mjs";
3
+ const DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY = '__modernDistributedSsrFragments';
4
+ const DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY = '__modernDistributedSsrFragmentRequest';
5
+ function distributedSsrFragmentKey(remote, expose) {
6
+ return `${remote}::${expose}`;
7
+ }
8
+ function getDistributedSsrFragmentContext(response) {
9
+ const locals = response?.locals;
10
+ if (!locals || 'object' != typeof locals) return;
11
+ const context = locals[DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY];
12
+ if (!context || 'object' != typeof context) return;
13
+ return context;
14
+ }
15
+ function useDistributedSsrFragmentProps({ boundaryId, expose }) {
16
+ const runtimeContext = useRuntimeContext();
17
+ const locals = runtimeContext.requestContext?.response?.locals;
18
+ const request = locals && 'object' == typeof locals ? locals[DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY] : void 0;
19
+ if (!request || 'object' != typeof request || request.boundaryId !== boundaryId || request.expose !== expose) throw new Error(`Distributed SSR fragment request contract mismatch for ${boundaryId} ${expose}.`);
20
+ const props = request.props;
21
+ if (!props || 'object' != typeof props || Array.isArray(props)) throw new Error(`Distributed SSR fragment request props must be an object for ${boundaryId} ${expose}.`);
22
+ return props;
23
+ }
24
+ function isThenable(value) {
25
+ return 'function' == typeof value.then;
26
+ }
27
+ function DistributedSsrBoundary({ children, expose, fallback, fragmentProps = {}, remote }) {
28
+ const runtimeContext = useRuntimeContext();
29
+ const key = distributedSsrFragmentKey(remote, expose);
30
+ const attributes = {
31
+ 'data-modern-distributed-ssr-boundary': key
32
+ };
33
+ if (runtimeContext.isBrowser) return /*#__PURE__*/ jsx("div", {
34
+ ...attributes,
35
+ children: children
36
+ });
37
+ const fragmentContext = getDistributedSsrFragmentContext(runtimeContext.requestContext?.response);
38
+ if (!fragmentContext) return /*#__PURE__*/ jsx("div", {
39
+ ...attributes,
40
+ children: children
41
+ });
42
+ const fragmentOrPromise = fragmentContext.resolve?.(remote, expose, fragmentProps) ?? fragmentContext.fragments?.[key];
43
+ if (fragmentOrPromise && isThenable(fragmentOrPromise)) throw fragmentOrPromise;
44
+ const fragment = fragmentOrPromise;
45
+ if (fragment?.status === 'ready') return /*#__PURE__*/ jsx("div", {
46
+ ...attributes,
47
+ "data-modern-distributed-ssr-build": fragment.buildMarker,
48
+ "data-modern-distributed-ssr-digest": fragment.digest,
49
+ "data-modern-distributed-ssr-status": "ready",
50
+ dangerouslySetInnerHTML: {
51
+ __html: fragment.html
52
+ }
53
+ });
54
+ return /*#__PURE__*/ jsx("div", {
55
+ ...attributes,
56
+ "data-modern-distributed-ssr-reason": fragment?.reason ?? 'missing',
57
+ "data-modern-distributed-ssr-status": "degraded",
58
+ children: fallback
59
+ });
60
+ }
61
+ function createDistributedSsrComponent({ createComponent, expose, fallback, remote }) {
62
+ let RemoteComponent;
63
+ function DeferredRemoteComponent(props) {
64
+ RemoteComponent ??= createComponent();
65
+ return /*#__PURE__*/ jsx(RemoteComponent, {
66
+ ...props
67
+ });
68
+ }
69
+ return function(props) {
70
+ return /*#__PURE__*/ jsx(DistributedSsrBoundary, {
71
+ expose: expose,
72
+ fallback: fallback,
73
+ fragmentProps: props,
74
+ remote: remote,
75
+ children: /*#__PURE__*/ jsx(DeferredRemoteComponent, {
76
+ ...props
77
+ })
78
+ });
79
+ };
80
+ }
81
+ export { DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY, DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY, DistributedSsrBoundary, createDistributedSsrComponent, distributedSsrFragmentKey, useDistributedSsrFragmentProps };
@@ -1,3 +1,8 @@
1
+ export * from "./consume-surface.mjs";
2
+ export * from "./distributed-ssr.mjs";
3
+ export * from "./last-known-good.mjs";
4
+ export * from "./manifest-recovery-runtime-plugin.mjs";
5
+ export * from "./surface-resolution-types.mjs";
1
6
  const MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT = 'modernjs:mf-runtime-fallback';
2
7
  const MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT = 'modernjs:mf-runtime-recovery';
3
8
  const DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT = '/_modern/contract-gates/runtime-fallback';
@@ -106,4 +111,5 @@ async function emitModuleFederationFallbackTelemetry(input, options = {}) {
106
111
  postStatus: response.status
107
112
  };
108
113
  }
114
+ export { DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY, useDistributedSsrFragmentProps } from "./distributed-ssr.mjs";
109
115
  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,80 @@
1
+ import { createDiscoveryError, deliveryUnitResolutionKey } from "./surface-resolution-types.mjs";
2
+ const LAST_KNOWN_GOOD_PROVIDER_NAME = 'last-known-good';
3
+ function createInMemoryLkgStorage() {
4
+ const map = new Map();
5
+ return {
6
+ read (key) {
7
+ return map.get(key);
8
+ },
9
+ write (key, record) {
10
+ map.set(key, record);
11
+ }
12
+ };
13
+ }
14
+ function markDegraded(resolved, reason) {
15
+ return {
16
+ ...resolved,
17
+ compatibility: {
18
+ ...resolved.compatibility,
19
+ status: 'degraded',
20
+ reason
21
+ }
22
+ };
23
+ }
24
+ function staleRecordResult(ref, env, ageMs, maxStaleMs) {
25
+ return {
26
+ ok: false,
27
+ error: createDiscoveryError('stale-record', ref, `Last-known-good record for surface is stale: age ${ageMs}ms exceeds maxStaleMs ${maxStaleMs}ms`, {
28
+ env,
29
+ ageMs,
30
+ maxStaleMs
31
+ })
32
+ };
33
+ }
34
+ function createLastKnownGoodProvider(options) {
35
+ const storage = options.storage ?? createInMemoryLkgStorage();
36
+ const now = options.now ?? (()=>Date.now());
37
+ const maxStaleMs = options.freshness?.maxStaleMs;
38
+ async function serveFromCache(ref, env, fallback) {
39
+ const key = deliveryUnitResolutionKey(ref.unitId, env);
40
+ const cached = await storage.read(key);
41
+ if (!cached) return fallback();
42
+ if (cached.major !== ref.major) return fallback();
43
+ if ('incompatible' === cached.resolved.compatibility.status) return fallback();
44
+ const ageMs = now() - cached.storedAt;
45
+ if (void 0 !== maxStaleMs && ageMs > maxStaleMs) return staleRecordResult(ref, env, ageMs, maxStaleMs);
46
+ return {
47
+ ok: true,
48
+ unit: markDegraded(cached.resolved, `served last-known-good record (age ${ageMs}ms) after provider failure`)
49
+ };
50
+ }
51
+ return {
52
+ name: LAST_KNOWN_GOOD_PROVIDER_NAME,
53
+ async resolve (ref, env) {
54
+ const key = deliveryUnitResolutionKey(ref.unitId, env);
55
+ let resolution;
56
+ try {
57
+ resolution = await options.provider.resolve(ref, env);
58
+ } catch (error) {
59
+ return serveFromCache(ref, env, ()=>({
60
+ ok: false,
61
+ error: createDiscoveryError('provider-unavailable', ref, error instanceof Error ? error.message : 'provider threw a non-error value', {
62
+ env,
63
+ provider: options.provider.name
64
+ })
65
+ }));
66
+ }
67
+ if (!resolution.ok) {
68
+ const failure = resolution;
69
+ return serveFromCache(ref, env, ()=>failure);
70
+ }
71
+ if ('incompatible' !== resolution.unit.compatibility.status) await storage.write(key, {
72
+ resolved: resolution.unit,
73
+ storedAt: now(),
74
+ major: ref.major
75
+ });
76
+ return resolution;
77
+ }
78
+ };
79
+ }
80
+ export { LAST_KNOWN_GOOD_PROVIDER_NAME, createInMemoryLkgStorage, createLastKnownGoodProvider };
@@ -0,0 +1,100 @@
1
+ const DEFAULT_ATTEMPTS = 3;
2
+ const DEFAULT_RETRY_DELAY_MS = 100;
3
+ const DEFAULT_TIMEOUT_MS = 1000;
4
+ const MAX_ATTEMPTS = 5;
5
+ const MAX_RETRY_DELAY_MS = 1000;
6
+ const MAX_TIMEOUT_MS = 5000;
7
+ const RETRYABLE_HTTP_STATUSES = new Set([
8
+ 408,
9
+ 425,
10
+ 429,
11
+ 500,
12
+ 502,
13
+ 503,
14
+ 504
15
+ ]);
16
+ const NON_RETRYABLE_ERROR_PATTERNS = [
17
+ /RUNTIME-013/i,
18
+ /invalid manifest/i,
19
+ /manifest (?:schema|contract|version|identity)/i,
20
+ /(?:incompatible|mismatch).*(?:manifest|remote)/i
21
+ ];
22
+ const clampInteger = (value, fallback, minimum, maximum)=>{
23
+ if (void 0 === value || !Number.isFinite(value)) return fallback;
24
+ return Math.min(maximum, Math.max(minimum, Math.floor(value)));
25
+ };
26
+ const getErrorMessage = (error)=>{
27
+ if (error instanceof Error) return error.message;
28
+ return 'string' == typeof error ? error : '';
29
+ };
30
+ const getErrorStatus = (error)=>{
31
+ if ('object' == typeof error && null !== error && 'status' in error && 'number' == typeof error.status) return error.status;
32
+ };
33
+ const isRetryableError = (error)=>{
34
+ if (error instanceof SyntaxError) return false;
35
+ const message = getErrorMessage(error);
36
+ if (NON_RETRYABLE_ERROR_PATTERNS.some((pattern)=>pattern.test(message))) return false;
37
+ const status = getErrorStatus(error);
38
+ if (void 0 !== status) return RETRYABLE_HTTP_STATUSES.has(status);
39
+ if (error instanceof Error && [
40
+ 'AbortError',
41
+ 'TimeoutError'
42
+ ].includes(error.name)) return true;
43
+ return error instanceof TypeError || /(?:fetch failed|network|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN)/i.test(message);
44
+ };
45
+ const isHttpManifestUrl = (id)=>{
46
+ if (!id) return false;
47
+ try {
48
+ const url = new URL(id);
49
+ return ('http:' === url.protocol || 'https:' === url.protocol) && url.pathname.endsWith('.json');
50
+ } catch {
51
+ return false;
52
+ }
53
+ };
54
+ const defaultWait = (milliseconds)=>new Promise((resolve)=>{
55
+ setTimeout(resolve, milliseconds);
56
+ });
57
+ const fetchWithTimeout = async (fetchImpl, url, timeoutMs)=>{
58
+ const controller = new AbortController();
59
+ const timeout = setTimeout(()=>controller.abort(), timeoutMs);
60
+ try {
61
+ return await fetchImpl(url, {
62
+ signal: controller.signal
63
+ });
64
+ } finally{
65
+ clearTimeout(timeout);
66
+ }
67
+ };
68
+ const createModuleFederationManifestRecoveryPlugin = (options = {})=>{
69
+ const attempts = clampInteger(options.attempts, DEFAULT_ATTEMPTS, 1, MAX_ATTEMPTS);
70
+ const retryDelayMs = clampInteger(options.retryDelayMs, DEFAULT_RETRY_DELAY_MS, 0, MAX_RETRY_DELAY_MS);
71
+ const timeoutMs = clampInteger(options.timeoutMs, DEFAULT_TIMEOUT_MS, 1, MAX_TIMEOUT_MS);
72
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
73
+ const waitImpl = options.waitImpl ?? defaultWait;
74
+ return {
75
+ name: 'modern-js-manifest-recovery-plugin',
76
+ async errorLoadRemote (args) {
77
+ if ('afterResolve' !== args.lifecycle || !isHttpManifestUrl(args.id) || !isRetryableError(args.error) || 'function' != typeof fetchImpl) return;
78
+ for(let attempt = 0; attempt < attempts; attempt++){
79
+ if (attempt > 0 && retryDelayMs > 0) await waitImpl(retryDelayMs);
80
+ try {
81
+ const response = await fetchWithTimeout(fetchImpl, args.id, timeoutMs);
82
+ if (!response.ok) {
83
+ if (!RETRYABLE_HTTP_STATUSES.has(response.status) || attempt === attempts - 1) return;
84
+ continue;
85
+ }
86
+ try {
87
+ return await response.json();
88
+ } catch {
89
+ break;
90
+ }
91
+ } catch (error) {
92
+ if (!isRetryableError(error) || attempt === attempts - 1) break;
93
+ }
94
+ }
95
+ }
96
+ };
97
+ };
98
+ const manifest_recovery_runtime_plugin = createModuleFederationManifestRecoveryPlugin;
99
+ export default manifest_recovery_runtime_plugin;
100
+ export { createModuleFederationManifestRecoveryPlugin };
@@ -0,0 +1,8 @@
1
+ import { createDiscoveryError, formatSurfaceRef, parseSurfaceRef, validateSurfaceRef } from "@modern-js/utils/universal";
2
+ function surfaceResolutionKey(ref, env) {
3
+ return `${env}::${formatSurfaceRef(ref)}`;
4
+ }
5
+ function deliveryUnitResolutionKey(unitId, env) {
6
+ return `${env}::${unitId}`;
7
+ }
8
+ export { createDiscoveryError, deliveryUnitResolutionKey, formatSurfaceRef, parseSurfaceRef, surfaceResolutionKey, validateSurfaceRef };
@@ -6,7 +6,7 @@ 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
8
  import { getServerCombinedModuleFile, getServerLoadersFile } from "./utils.mjs";
9
- import * as __rspack_external__templates_mjs_4da4c6c8 from "./templates.mjs";
9
+ import * as __rspack_external__templates_mjs_ab577925 from "./templates.mjs";
10
10
  async function generateRoutesForEntry(entrypoint, appContext) {
11
11
  const routes = [];
12
12
  if (entrypoint.nestedRoutesEntry) {
@@ -89,7 +89,7 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
89
89
  }
90
90
  const { code } = await hooks.onBeforeGenerateRoutes.call({
91
91
  entrypoint,
92
- code: await __rspack_external__templates_mjs_4da4c6c8.fileSystemRoutes({
92
+ code: await __rspack_external__templates_mjs_ab577925.fileSystemRoutes({
93
93
  metaName,
94
94
  routes: routes,
95
95
  ssrMode: isUseRsc(config) ? 'stream' : ssrMode,
@@ -106,12 +106,12 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
106
106
  const routesServerFile = getServerLoadersFile(internalDirectory, entryName);
107
107
  const filtedRoutesForServer = filterRoutesForServer(routes);
108
108
  const routesForServerLoaderMatches = filterRoutesLoader(routes);
109
- const code = __rspack_external__templates_mjs_4da4c6c8.routesForServer({
109
+ const code = __rspack_external__templates_mjs_ab577925.routesForServer({
110
110
  routesForServerLoaderMatches
111
111
  });
112
112
  await fs.ensureFile(routesServerFile);
113
113
  await fs.writeFile(routesServerFile, code);
114
- const serverRoutesCode = await __rspack_external__templates_mjs_4da4c6c8.fileSystemRoutes({
114
+ const serverRoutesCode = await __rspack_external__templates_mjs_ab577925.fileSystemRoutes({
115
115
  metaName,
116
116
  routes: filtedRoutesForServer,
117
117
  ssrMode,
@@ -125,7 +125,7 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
125
125
  });
126
126
  await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, 'utf8');
127
127
  }
128
- const serverLoaderCombined = __rspack_external__templates_mjs_4da4c6c8.ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext);
128
+ const serverLoaderCombined = __rspack_external__templates_mjs_ab577925.ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext);
129
129
  if (serverLoaderCombined) {
130
130
  const serverLoaderFile = getServerCombinedModuleFile(internalDirectory, entryName);
131
131
  await fs.outputFile(serverLoaderFile, serverLoaderCombined);
@@ -82,6 +82,7 @@ const walk = async (options)=>{
82
82
  let pageLoaderFile = '';
83
83
  let pageRoute = null;
84
84
  let pageConfigFile = '';
85
+ let pageSearchFile = '';
85
86
  let pageClientData = '';
86
87
  let pageData = '';
87
88
  let pageAction = '';
@@ -128,12 +129,14 @@ const walk = async (options)=>{
128
129
  if (await hasAction(itemPath)) pageAction = itemPathWithAlias;
129
130
  }
130
131
  if (itemWithoutExt === NESTED_ROUTE.PAGE_CONFIG_FILE) pageConfigFile = itemPathWithAlias;
132
+ if (itemWithoutExt === NESTED_ROUTE.PAGE_SEARCH_FILE) pageSearchFile = itemPathWithAlias;
131
133
  if (itemWithoutExt === NESTED_ROUTE.PAGE_FILE) {
132
134
  pageRoute = createIndexRoute({
133
135
  _component: itemPathWithAlias
134
136
  }, rootDir, itemPath, entryName, isMainEntry);
135
137
  if (pageLoaderFile) pageRoute.loader = pageLoaderFile;
136
138
  if (pageConfigFile) pageRoute.config = pageConfigFile;
139
+ if (pageSearchFile) pageRoute.validateSearch = pageSearchFile;
137
140
  if (pageData) pageRoute.data = pageData;
138
141
  if (pageClientData) pageRoute.clientData = pageClientData;
139
142
  if (pageAction) pageRoute.action = pageAction;
@@ -182,7 +182,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
182
182
  component = `component_${components.length - 1}`;
183
183
  }
184
184
  const isClientComponent = 'nested' === route.type && Boolean(route._component) && Boolean(srcDirectory) && Boolean(internalSrcAlias) && await hasUseClientDirective(route._component, srcDirectory, internalSrcAlias);
185
- const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent;
185
+ const shouldHydrateRscRoute = isRscClientBundle && !isClientComponent && !route.loader && !route.data;
186
+ const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent || shouldHydrateRscRoute;
186
187
  const finalRoute = {
187
188
  ...route,
188
189
  loading,
@@ -285,7 +286,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
285
286
  ${importLazyCode}
286
287
  ${!isRscClientBundle ? importComponentsCode : ''}
287
288
  ${importRuntimeRouterCode}
288
- ${!isRscClientBundle ? rootLayoutCode : ''}
289
+ ${rootLayoutCode}
289
290
  ${importLoadingCode}
290
291
  ${importErrorComponentsCode}
291
292
  ${importLoadersCode}
@@ -18,6 +18,7 @@ const NESTED_ROUTE = {
18
18
  PAGE_FILE: 'page',
19
19
  PAGE_CONFIG_FILE: 'page.config',
20
20
  PAGE_LOADER_FILE: 'page.loader',
21
+ PAGE_SEARCH_FILE: 'page.search',
21
22
  PAGE_DATA_FILE: 'page.data',
22
23
  PAGE_CLIENT_LOADER: 'page.data.client',
23
24
  SPLATE_FILE: '$',
@@ -3,7 +3,7 @@ import { cloneDeep } from "@modern-js/utils/lodash";
3
3
  import path from "path";
4
4
  import { isPageComponentFile } from "./code/utils.mjs";
5
5
  import { modifyEntrypoints } from "./entry.mjs";
6
- import * as __rspack_external__code_templates_mjs_5e908598 from "./code/templates.mjs";
6
+ import * as __rspack_external__code_templates_mjs_f6c22489 from "./code/templates.mjs";
7
7
  const DEFAULT_ENTRYPOINTS_KEY = '__default_router_entries__';
8
8
  const originEntrypointsByKey = new Map();
9
9
  async function handleModifyEntrypoints(entrypoints, routesDir, options = {}) {
@@ -25,7 +25,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
25
25
  if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
26
26
  const route = appContext.serverRoutes.find((r)=>r.entryName === entrypoint.entryName);
27
27
  const basename = route?.urlPath || '/';
28
- generatorRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_5e908598.runtimeGlobalContext({
28
+ generatorRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_f6c22489.runtimeGlobalContext({
29
29
  entryName: entrypoint.entryName,
30
30
  metaName: appContext.metaName,
31
31
  srcDirectory: appContext.srcDirectory,
@@ -35,7 +35,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
35
35
  rscType: enableRsc ? 'client' : void 0,
36
36
  basename
37
37
  }));
38
- if (enableRsc) generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_5e908598.runtimeGlobalContext({
38
+ if (enableRsc) generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_f6c22489.runtimeGlobalContext({
39
39
  entryName: entrypoint.entryName,
40
40
  metaName: appContext.metaName,
41
41
  srcDirectory: appContext.srcDirectory,
@@ -1,6 +1,7 @@
1
1
  import node_path from "node:path";
2
2
  import { setTimeout as promises_setTimeout } from "node:timers/promises";
3
3
  import { fs } from "@modern-js/utils";
4
+ import { cloneDeep } from "@modern-js/utils/lodash";
4
5
  const lockPollIntervalMs = 25;
5
6
  const staleLockAgeMs = 120000;
6
7
  const pendingUpdates = new Map();
@@ -43,6 +44,7 @@ async function writeJSONAtomically(filePath, value) {
43
44
  }
44
45
  async function updateNestedRoutesSpec(specPath, nextRoutes) {
45
46
  const resolvedSpecPath = node_path.resolve(specPath);
47
+ const nextRoutesSnapshot = cloneDeep(nextRoutes);
46
48
  const previousUpdate = pendingUpdates.get(resolvedSpecPath) ?? Promise.resolve();
47
49
  const currentUpdate = previousUpdate.catch(()=>void 0).then(async ()=>{
48
50
  const releaseLock = await acquireSpecLock(resolvedSpecPath);
@@ -50,7 +52,7 @@ async function updateNestedRoutesSpec(specPath, nextRoutes) {
50
52
  const existingRoutes = await fs.pathExists(resolvedSpecPath) ? await fs.readJSON(resolvedSpecPath) : {};
51
53
  await writeJSONAtomically(resolvedSpecPath, {
52
54
  ...existingRoutes,
53
- ...nextRoutes
55
+ ...nextRoutesSnapshot
54
56
  });
55
57
  } finally{
56
58
  await releaseLock();