@bleedingdev/modern-js-federation-runtime 0.0.0 → 3.9.0-ultramodern.6

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 (33) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/module-federation/consume-surface.js +199 -0
  3. package/dist/cjs/module-federation/distributed-ssr.js +135 -0
  4. package/dist/cjs/module-federation/index.js +316 -0
  5. package/dist/cjs/module-federation/last-known-good.js +157 -0
  6. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +130 -0
  7. package/dist/cjs/module-federation/surface-resolution-types.js +61 -0
  8. package/dist/esm/module-federation/consume-surface.mjs +158 -0
  9. package/dist/esm/module-federation/distributed-ssr.mjs +82 -0
  10. package/dist/esm/module-federation/index.mjs +115 -0
  11. package/dist/esm/module-federation/last-known-good.mjs +113 -0
  12. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +90 -0
  13. package/dist/esm/module-federation/surface-resolution-types.mjs +8 -0
  14. package/dist/esm-node/module-federation/consume-surface.mjs +159 -0
  15. package/dist/esm-node/module-federation/distributed-ssr.mjs +83 -0
  16. package/dist/esm-node/module-federation/index.mjs +116 -0
  17. package/dist/esm-node/module-federation/last-known-good.mjs +114 -0
  18. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +91 -0
  19. package/dist/esm-node/module-federation/surface-resolution-types.mjs +9 -0
  20. package/dist/types/module-federation/consume-surface.d.ts +104 -0
  21. package/dist/types/module-federation/distributed-ssr.d.ts +61 -0
  22. package/dist/types/module-federation/index.d.ts +71 -0
  23. package/dist/types/module-federation/last-known-good.d.ts +52 -0
  24. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +25 -0
  25. package/dist/types/module-federation/surface-resolution-types.d.ts +23 -0
  26. package/package.json +86 -4
  27. package/src/module-federation/consume-surface.ts +369 -0
  28. package/src/module-federation/distributed-ssr.tsx +240 -0
  29. package/src/module-federation/index.ts +274 -0
  30. package/src/module-federation/last-known-good.ts +292 -0
  31. package/src/module-federation/manifest-recovery-runtime-plugin.ts +215 -0
  32. package/src/module-federation/surface-resolution-types.ts +60 -0
  33. package/README.md +0 -3
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ LAST_KNOWN_GOOD_PROVIDER_NAME: ()=>LAST_KNOWN_GOOD_PROVIDER_NAME,
32
+ createInMemoryLkgStorage: ()=>createInMemoryLkgStorage,
33
+ createLastKnownGoodProvider: ()=>createLastKnownGoodProvider
34
+ });
35
+ const surface_resolution_namespaceObject = require("@modern-js/surface-resolution");
36
+ const external_surface_resolution_types_js_namespaceObject = require("./surface-resolution-types.js");
37
+ const LAST_KNOWN_GOOD_PROVIDER_NAME = 'last-known-good';
38
+ function createInMemoryLkgStorage() {
39
+ const map = new Map();
40
+ return {
41
+ read (key) {
42
+ return map.get(key);
43
+ },
44
+ write (key, record) {
45
+ map.set(key, record);
46
+ }
47
+ };
48
+ }
49
+ function markDegraded(resolved, reason) {
50
+ return {
51
+ ...resolved,
52
+ compatibility: {
53
+ ...resolved.compatibility,
54
+ status: 'degraded',
55
+ reason
56
+ }
57
+ };
58
+ }
59
+ function staleRecordResult(ref, env, ageMs, maxStaleMs) {
60
+ return {
61
+ ok: false,
62
+ error: (0, external_surface_resolution_types_js_namespaceObject.createDiscoveryError)('stale-record', ref, `Last-known-good record for surface is stale: age ${ageMs}ms exceeds maxStaleMs ${maxStaleMs}ms`, {
63
+ env,
64
+ ageMs,
65
+ maxStaleMs
66
+ })
67
+ };
68
+ }
69
+ function resolutionAnswersRef(resolved, ref) {
70
+ const selected = (0, surface_resolution_namespaceObject.selectResolvedSurface)(resolved, ref);
71
+ return selected.ok && selected.surface.servedMajor === ref.major;
72
+ }
73
+ function createLastKnownGoodProvider(options) {
74
+ const storage = options.storage ?? createInMemoryLkgStorage();
75
+ const now = options.now ?? (()=>Math.floor(performance.timeOrigin + performance.now()));
76
+ const maxStaleMs = options.freshness?.maxStaleMs;
77
+ let nextResolutionGeneration = 0;
78
+ const latestCacheableGenerationByKey = new Map();
79
+ const writeTailByKey = new Map();
80
+ async function cacheCompatibleResolution(key, generation, record) {
81
+ latestCacheableGenerationByKey.set(key, Math.max(latestCacheableGenerationByKey.get(key) ?? 0, generation));
82
+ const previous = writeTailByKey.get(key) ?? Promise.resolve();
83
+ const write = previous.catch(()=>void 0).then(async ()=>{
84
+ if (latestCacheableGenerationByKey.get(key) !== generation) return;
85
+ await storage.write(key, record);
86
+ });
87
+ writeTailByKey.set(key, write);
88
+ try {
89
+ await write;
90
+ } finally{
91
+ if (writeTailByKey.get(key) === write) writeTailByKey.delete(key);
92
+ }
93
+ }
94
+ async function serveFromCache(ref, env, fallback) {
95
+ const key = (0, external_surface_resolution_types_js_namespaceObject.deliveryUnitResolutionKey)(ref.unitId, env);
96
+ const cached = await storage.read(key);
97
+ if (!cached) return fallback();
98
+ if (cached.major !== ref.major) return fallback();
99
+ if (!resolutionAnswersRef(cached.resolved, ref)) return fallback();
100
+ if ('compatible' !== cached.resolved.compatibility.status) return fallback();
101
+ const ageMs = now() - cached.storedAt;
102
+ if (void 0 !== maxStaleMs && ageMs > maxStaleMs) return staleRecordResult(ref, env, ageMs, maxStaleMs);
103
+ return {
104
+ ok: true,
105
+ unit: markDegraded(cached.resolved, `served last-known-good record (age ${ageMs}ms) after provider failure`)
106
+ };
107
+ }
108
+ return {
109
+ name: LAST_KNOWN_GOOD_PROVIDER_NAME,
110
+ async resolve (ref, env) {
111
+ const key = (0, external_surface_resolution_types_js_namespaceObject.deliveryUnitResolutionKey)(ref.unitId, env);
112
+ const generation = ++nextResolutionGeneration;
113
+ let resolution;
114
+ try {
115
+ resolution = await options.provider.resolve(ref, env);
116
+ } catch (error) {
117
+ return serveFromCache(ref, env, ()=>({
118
+ ok: false,
119
+ error: (0, external_surface_resolution_types_js_namespaceObject.createDiscoveryError)('provider-unavailable', ref, error instanceof Error ? error.message : 'provider threw a non-error value', {
120
+ env,
121
+ provider: options.provider.name
122
+ })
123
+ }));
124
+ }
125
+ if (!resolution.ok) {
126
+ const failure = resolution;
127
+ return serveFromCache(ref, env, ()=>failure);
128
+ }
129
+ if (!resolutionAnswersRef(resolution.unit, ref)) return serveFromCache(ref, env, ()=>({
130
+ ok: false,
131
+ error: (0, external_surface_resolution_types_js_namespaceObject.createDiscoveryError)('identity-mismatch', ref, `Provider ${options.provider.name} returned a delivery unit that does not answer the requested surface.`, {
132
+ env,
133
+ provider: options.provider.name,
134
+ recordUnitId: resolution.unit.unitId,
135
+ availableSurfaces: resolution.unit.surfaces.map((surface)=>surface.surfaceId)
136
+ })
137
+ }));
138
+ if ('compatible' === resolution.unit.compatibility.status) await cacheCompatibleResolution(key, generation, {
139
+ resolved: resolution.unit,
140
+ storedAt: now(),
141
+ major: ref.major
142
+ });
143
+ return resolution;
144
+ }
145
+ };
146
+ }
147
+ exports.LAST_KNOWN_GOOD_PROVIDER_NAME = __webpack_exports__.LAST_KNOWN_GOOD_PROVIDER_NAME;
148
+ exports.createInMemoryLkgStorage = __webpack_exports__.createInMemoryLkgStorage;
149
+ exports.createLastKnownGoodProvider = __webpack_exports__.createLastKnownGoodProvider;
150
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
151
+ "LAST_KNOWN_GOOD_PROVIDER_NAME",
152
+ "createInMemoryLkgStorage",
153
+ "createLastKnownGoodProvider"
154
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
155
+ Object.defineProperty(exports, '__esModule', {
156
+ value: true
157
+ });
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ const DEFAULT_ATTEMPTS = 3;
31
+ const DEFAULT_RETRY_DELAY_MS = 100;
32
+ const DEFAULT_TIMEOUT_MS = 1000;
33
+ const MAX_ATTEMPTS = 5;
34
+ const MAX_RETRY_DELAY_MS = 1000;
35
+ const MAX_TIMEOUT_MS = 5000;
36
+ const RETRYABLE_HTTP_STATUSES = new Set([
37
+ 408,
38
+ 425,
39
+ 429,
40
+ 500,
41
+ 502,
42
+ 503,
43
+ 504
44
+ ]);
45
+ const NON_RETRYABLE_ERROR_PATTERNS = [
46
+ /RUNTIME-013/i,
47
+ /invalid manifest/i,
48
+ /manifest (?:schema|contract|version|identity)/i,
49
+ /(?:incompatible|mismatch).*(?:manifest|remote)/i
50
+ ];
51
+ const clampInteger = (value, fallback, minimum, maximum)=>{
52
+ if (void 0 === value || !Number.isFinite(value)) return fallback;
53
+ return Math.min(maximum, Math.max(minimum, Math.floor(value)));
54
+ };
55
+ const getErrorMessage = (error)=>{
56
+ if (error instanceof Error) return error.message;
57
+ return 'string' == typeof error ? error : '';
58
+ };
59
+ const getErrorStatus = (error)=>{
60
+ if ('object' == typeof error && null !== error && 'status' in error && 'number' == typeof error.status) return error.status;
61
+ };
62
+ const isRetryableError = (error)=>{
63
+ if (error instanceof SyntaxError) return false;
64
+ const message = getErrorMessage(error);
65
+ if (NON_RETRYABLE_ERROR_PATTERNS.some((pattern)=>pattern.test(message))) return false;
66
+ const status = getErrorStatus(error);
67
+ if (void 0 !== status) return RETRYABLE_HTTP_STATUSES.has(status);
68
+ if (error instanceof Error && [
69
+ 'AbortError',
70
+ 'TimeoutError'
71
+ ].includes(error.name)) return true;
72
+ return error instanceof TypeError || /(?:fetch failed|network|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN)/i.test(message);
73
+ };
74
+ const isHttpManifestUrl = (id)=>{
75
+ if (void 0 === id || 0 === id.length) return false;
76
+ try {
77
+ const url = new URL(id);
78
+ return ('http:' === url.protocol || 'https:' === url.protocol) && url.pathname.endsWith('.json');
79
+ } catch {
80
+ return false;
81
+ }
82
+ };
83
+ const defaultWait = (milliseconds)=>new Promise((resolve)=>{
84
+ setTimeout(resolve, milliseconds);
85
+ });
86
+ const fetchWithTimeout = (fetchImpl, url, timeoutMs)=>fetchImpl(url, {
87
+ signal: AbortSignal.timeout(timeoutMs)
88
+ });
89
+ const createModuleFederationManifestRecoveryPlugin = (options = {})=>{
90
+ const attempts = clampInteger(options.attempts, DEFAULT_ATTEMPTS, 1, MAX_ATTEMPTS);
91
+ const retryDelayMs = clampInteger(options.retryDelayMs, DEFAULT_RETRY_DELAY_MS, 0, MAX_RETRY_DELAY_MS);
92
+ const timeoutMs = clampInteger(options.timeoutMs, DEFAULT_TIMEOUT_MS, 1, MAX_TIMEOUT_MS);
93
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
94
+ const waitImpl = options.waitImpl ?? defaultWait;
95
+ const recoverManifest = (url, attempt)=>{
96
+ const fetchManifest = ()=>Promise.resolve().then(()=>fetchWithTimeout(fetchImpl, url, timeoutMs)).then((response)=>{
97
+ if (!response.ok) {
98
+ if (!RETRYABLE_HTTP_STATUSES.has(response.status) || attempt === attempts - 1) return;
99
+ return recoverManifest(url, attempt + 1);
100
+ }
101
+ return Promise.resolve().then(()=>response.json()).then((manifest)=>manifest, ()=>void 0);
102
+ }, (error)=>{
103
+ if (!isRetryableError(error) || attempt === attempts - 1) return;
104
+ return recoverManifest(url, attempt + 1);
105
+ });
106
+ if (attempt > 0 && retryDelayMs > 0) return waitImpl(retryDelayMs).then(fetchManifest);
107
+ return fetchManifest();
108
+ };
109
+ return {
110
+ name: 'modern-js-manifest-recovery-plugin',
111
+ errorLoadRemote (args) {
112
+ if ('afterResolve' !== args.lifecycle || !isHttpManifestUrl(args.id) || !isRetryableError(args.error) || 'function' != typeof fetchImpl) return Promise.resolve(void 0);
113
+ return recoverManifest(args.id, 0);
114
+ }
115
+ };
116
+ };
117
+ const __rspack_default_export = createModuleFederationManifestRecoveryPlugin;
118
+ __webpack_require__.d(__webpack_exports__, {}, {
119
+ createModuleFederationManifestRecoveryPlugin: createModuleFederationManifestRecoveryPlugin,
120
+ default: __rspack_default_export
121
+ });
122
+ exports.createModuleFederationManifestRecoveryPlugin = __webpack_exports__.createModuleFederationManifestRecoveryPlugin;
123
+ exports["default"] = __webpack_exports__["default"];
124
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
125
+ "createModuleFederationManifestRecoveryPlugin",
126
+ "default"
127
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
128
+ Object.defineProperty(exports, '__esModule', {
129
+ value: true
130
+ });
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ createDiscoveryError: ()=>surface_resolution_namespaceObject.createDiscoveryError,
32
+ deliveryUnitResolutionKey: ()=>deliveryUnitResolutionKey,
33
+ formatSurfaceRef: ()=>surface_resolution_namespaceObject.formatSurfaceRef,
34
+ parseSurfaceRef: ()=>surface_resolution_namespaceObject.parseSurfaceRef,
35
+ surfaceResolutionKey: ()=>surfaceResolutionKey,
36
+ validateSurfaceRef: ()=>surface_resolution_namespaceObject.validateSurfaceRef
37
+ });
38
+ const surface_resolution_namespaceObject = require("@modern-js/surface-resolution");
39
+ function surfaceResolutionKey(ref, env) {
40
+ return `${env}::${(0, surface_resolution_namespaceObject.formatSurfaceRef)(ref)}`;
41
+ }
42
+ function deliveryUnitResolutionKey(unitId, env) {
43
+ return `${env}::${unitId}`;
44
+ }
45
+ exports.createDiscoveryError = __webpack_exports__.createDiscoveryError;
46
+ exports.deliveryUnitResolutionKey = __webpack_exports__.deliveryUnitResolutionKey;
47
+ exports.formatSurfaceRef = __webpack_exports__.formatSurfaceRef;
48
+ exports.parseSurfaceRef = __webpack_exports__.parseSurfaceRef;
49
+ exports.surfaceResolutionKey = __webpack_exports__.surfaceResolutionKey;
50
+ exports.validateSurfaceRef = __webpack_exports__.validateSurfaceRef;
51
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
52
+ "createDiscoveryError",
53
+ "deliveryUnitResolutionKey",
54
+ "formatSurfaceRef",
55
+ "parseSurfaceRef",
56
+ "surfaceResolutionKey",
57
+ "validateSurfaceRef"
58
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
59
+ Object.defineProperty(exports, '__esModule', {
60
+ value: true
61
+ });
@@ -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,82 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useRuntimeContext } from "@modern-js/runtime";
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 ('object' != typeof locals || null === locals) return;
11
+ const context = DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY in locals ? locals[DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY] : void 0;
12
+ if ('object' != typeof context || null === 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 = 'object' == typeof locals && null !== locals && DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY in locals ? locals[DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY] : void 0;
19
+ if ('object' != typeof request || null === request || !('boundaryId' in request) || request.boundaryId !== boundaryId || !('expose' in request) || request.expose !== expose) throw new Error(`Distributed SSR fragment request contract mismatch for ${boundaryId} ${expose}.`);
20
+ const props = 'props' in request ? request.props : void 0;
21
+ if ('object' != typeof props || null === 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 void 0 !== value && 'then' in value && '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 (void 0 === fragmentContext) return /*#__PURE__*/ jsx("div", {
39
+ ...attributes,
40
+ children: children
41
+ });
42
+ const resolverFragmentProps = void 0 === fragmentProps ? {} : Object.fromEntries(Object.entries(fragmentProps));
43
+ const fragmentOrPromise = fragmentContext.resolve?.(remote, expose, resolverFragmentProps) ?? fragmentContext.fragments?.[key];
44
+ if (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 };