@bleedingdev/modern-js-federation-runtime 3.9.0-ultramodern.9 → 3.9.3-ultramodern.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/module-federation/consume-surface.js +6 -16
- package/dist/cjs/module-federation/distributed-ssr.js +6 -1
- package/dist/cjs/module-federation/index.js +13 -239
- package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +1 -1
- package/dist/cjs/module-federation/renderer-contract.js +159 -0
- package/dist/cjs/module-federation/renderer-runtime-plugin.js +265 -0
- package/dist/cjs/module-federation/telemetry.js +214 -0
- package/dist/esm/module-federation/consume-surface.mjs +3 -13
- package/dist/esm/module-federation/distributed-ssr.mjs +6 -1
- package/dist/esm/module-federation/index.mjs +1 -111
- package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +1 -1
- package/dist/esm/module-federation/renderer-contract.mjs +103 -0
- package/dist/esm/module-federation/renderer-runtime-plugin.mjs +222 -0
- package/dist/esm/module-federation/telemetry.mjs +142 -0
- package/dist/esm-node/module-federation/consume-surface.mjs +3 -13
- package/dist/esm-node/module-federation/distributed-ssr.mjs +6 -1
- package/dist/esm-node/module-federation/index.mjs +1 -111
- package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +1 -1
- package/dist/esm-node/module-federation/renderer-contract.mjs +104 -0
- package/dist/esm-node/module-federation/renderer-runtime-plugin.mjs +223 -0
- package/dist/esm-node/module-federation/telemetry.mjs +143 -0
- package/dist/types/module-federation/consume-surface.d.ts +5 -5
- package/dist/types/module-federation/distributed-ssr.d.ts +18 -1
- package/dist/types/module-federation/index.d.ts +1 -67
- package/dist/types/module-federation/renderer-contract.d.ts +20 -0
- package/dist/types/module-federation/renderer-runtime-plugin.d.ts +98 -0
- package/dist/types/module-federation/telemetry.d.ts +71 -0
- package/package.json +54 -18
- package/src/module-federation/consume-surface.ts +18 -33
- package/src/module-federation/distributed-ssr.tsx +27 -2
- package/src/module-federation/index.ts +1 -267
- package/src/module-federation/manifest-recovery-runtime-plugin.ts +5 -1
- package/src/module-federation/renderer-contract.ts +176 -0
- package/src/module-federation/renderer-runtime-plugin.ts +396 -0
- package/src/module-federation/telemetry.ts +297 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type RendererFederationCompatibility } from './renderer-contract.js';
|
|
2
|
+
type Snapshot = Record<string, unknown>;
|
|
3
|
+
type SnapshotArgs = {
|
|
4
|
+
remoteSnapshot: Snapshot;
|
|
5
|
+
from: 'global' | 'manifest';
|
|
6
|
+
manifestJson?: unknown;
|
|
7
|
+
};
|
|
8
|
+
type Shared = Record<string, unknown> & {
|
|
9
|
+
version?: string;
|
|
10
|
+
};
|
|
11
|
+
type ShareResolution = {
|
|
12
|
+
shared: Shared;
|
|
13
|
+
useTreesShaking?: boolean;
|
|
14
|
+
} | undefined;
|
|
15
|
+
type ResolveShareArgs = {
|
|
16
|
+
pkgName: string;
|
|
17
|
+
shareScopeMap: Record<string, Record<string, Record<string, Shared>>>;
|
|
18
|
+
resolver: () => ShareResolution;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Exact versions every shared copy of the consuming renderer tuple must carry.
|
|
22
|
+
* React keeps its established package set; native renderers derive theirs from
|
|
23
|
+
* the tuple's runtime, hydration, bootstrap and router owners.
|
|
24
|
+
*/
|
|
25
|
+
export declare function rendererShareVersions(expected: RendererFederationCompatibility): ReadonlyMap<string, string>;
|
|
26
|
+
/** Gate the native snapshot and share lifecycles before executing component factories. */
|
|
27
|
+
export declare function createRendererFederationRuntimePlugin(options: RendererFederationCompatibility): {
|
|
28
|
+
name: string;
|
|
29
|
+
beforeRegisterRemote(args: {
|
|
30
|
+
remote: unknown;
|
|
31
|
+
}): {
|
|
32
|
+
remote: unknown;
|
|
33
|
+
};
|
|
34
|
+
afterMatchRemote(args: {
|
|
35
|
+
remote?: unknown;
|
|
36
|
+
error?: unknown;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
remote?: unknown;
|
|
39
|
+
error?: unknown;
|
|
40
|
+
}>;
|
|
41
|
+
loadRemoteSnapshot(args: SnapshotArgs): Promise<SnapshotArgs>;
|
|
42
|
+
afterLoadSnapshot(args: {
|
|
43
|
+
remoteSnapshot: Snapshot;
|
|
44
|
+
moduleInfo?: {
|
|
45
|
+
name: string;
|
|
46
|
+
};
|
|
47
|
+
}): Promise<{
|
|
48
|
+
remoteSnapshot: Snapshot;
|
|
49
|
+
moduleInfo?: {
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
}>;
|
|
53
|
+
afterResolve(args: {
|
|
54
|
+
remote: {
|
|
55
|
+
name: string;
|
|
56
|
+
};
|
|
57
|
+
remoteInfo: Record<string, unknown>;
|
|
58
|
+
remoteSnapshot?: Snapshot;
|
|
59
|
+
origin: {
|
|
60
|
+
moduleCache: Map<string, {
|
|
61
|
+
remoteInfo: Record<string, unknown>;
|
|
62
|
+
}>;
|
|
63
|
+
};
|
|
64
|
+
}): Promise<{
|
|
65
|
+
remote: {
|
|
66
|
+
name: string;
|
|
67
|
+
};
|
|
68
|
+
remoteInfo: Record<string, unknown>;
|
|
69
|
+
remoteSnapshot?: Snapshot;
|
|
70
|
+
origin: {
|
|
71
|
+
moduleCache: Map<string, {
|
|
72
|
+
remoteInfo: Record<string, unknown>;
|
|
73
|
+
}>;
|
|
74
|
+
};
|
|
75
|
+
}>;
|
|
76
|
+
loadEntry(args: {
|
|
77
|
+
remoteInfo: Record<string, unknown>;
|
|
78
|
+
}): void;
|
|
79
|
+
afterLoadEntry(args: {
|
|
80
|
+
remoteInfo: Record<string, unknown>;
|
|
81
|
+
remoteEntryExports?: unknown;
|
|
82
|
+
cached?: boolean;
|
|
83
|
+
error?: unknown;
|
|
84
|
+
recovered?: boolean;
|
|
85
|
+
}): Promise<{
|
|
86
|
+
remoteInfo: Record<string, unknown>;
|
|
87
|
+
remoteEntryExports?: unknown;
|
|
88
|
+
cached?: boolean;
|
|
89
|
+
error?: unknown;
|
|
90
|
+
recovered?: boolean;
|
|
91
|
+
}>;
|
|
92
|
+
resolveShare(args: ResolveShareArgs): ResolveShareArgs;
|
|
93
|
+
afterLoadShare(args: {
|
|
94
|
+
pkgName: string;
|
|
95
|
+
selectedShared?: Shared;
|
|
96
|
+
}): void;
|
|
97
|
+
};
|
|
98
|
+
export default createRendererFederationRuntimePlugin;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export declare const MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT = "modernjs:mf-runtime-fallback";
|
|
2
|
+
export declare const MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT = "modernjs:mf-runtime-recovery";
|
|
3
|
+
export declare const DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT = "/_modern/contract-gates/runtime-fallback";
|
|
4
|
+
export declare const DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER = "x-modernjs-runtime-signal-token";
|
|
5
|
+
export type ModuleFederationFallbackClassification = 'timeout' | 'network' | 'contract' | 'version-skew' | 'remote-unavailable';
|
|
6
|
+
export type ModuleFederationFallbackStatus = 'degraded' | 'failed' | 'recovered';
|
|
7
|
+
export type ModuleFederationFallbackTelemetryInput = {
|
|
8
|
+
appName: string;
|
|
9
|
+
classification: ModuleFederationFallbackClassification;
|
|
10
|
+
entry?: string;
|
|
11
|
+
error?: unknown;
|
|
12
|
+
eventName?: string;
|
|
13
|
+
exportName?: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
phase: 'discovery' | 'load' | 'mount' | 'hydrate' | 'recover';
|
|
16
|
+
remote: string;
|
|
17
|
+
runtimeDigest?: string;
|
|
18
|
+
status?: ModuleFederationFallbackStatus;
|
|
19
|
+
};
|
|
20
|
+
export type ModuleFederationFallbackTelemetryPayload = {
|
|
21
|
+
appName: string;
|
|
22
|
+
entry?: string;
|
|
23
|
+
eventName: string;
|
|
24
|
+
phase: ModuleFederationFallbackTelemetryInput['phase'];
|
|
25
|
+
reason: ModuleFederationFallbackClassification;
|
|
26
|
+
runtimeDigest?: string;
|
|
27
|
+
schemaVersion: 1;
|
|
28
|
+
metadata: {
|
|
29
|
+
classification: ModuleFederationFallbackClassification;
|
|
30
|
+
errorMessage?: string;
|
|
31
|
+
errorName?: string;
|
|
32
|
+
exportName?: string;
|
|
33
|
+
remote: string;
|
|
34
|
+
runtimeDigest?: string;
|
|
35
|
+
status: ModuleFederationFallbackStatus;
|
|
36
|
+
} & Record<string, unknown>;
|
|
37
|
+
};
|
|
38
|
+
export type ModuleFederationFallbackTelemetryEmitOptions = {
|
|
39
|
+
authHeaderName?: string;
|
|
40
|
+
authToken?: string;
|
|
41
|
+
endpoint?: string;
|
|
42
|
+
fetchImpl?: typeof fetch;
|
|
43
|
+
postSignal?: boolean;
|
|
44
|
+
/** Positive reporting deadline; defaults to one second. */
|
|
45
|
+
timeoutMs?: number;
|
|
46
|
+
/** Observe the exact payload and await delivery explicitly in tests. */
|
|
47
|
+
observe?: (payload: ModuleFederationFallbackTelemetryPayload, delivery: Promise<ModuleFederationFallbackTelemetryEmitResult>) => void;
|
|
48
|
+
};
|
|
49
|
+
export type ModuleFederationFallbackTelemetryEmitResult = {
|
|
50
|
+
dispatched: boolean;
|
|
51
|
+
posted: boolean;
|
|
52
|
+
postStatus?: number;
|
|
53
|
+
};
|
|
54
|
+
export declare class ModuleFederationRemoteLoadTimeoutError extends Error {
|
|
55
|
+
constructor(remote: string, timeoutMs: number);
|
|
56
|
+
}
|
|
57
|
+
export declare class ModuleFederationRemoteLoadError extends Error {
|
|
58
|
+
readonly remote: string;
|
|
59
|
+
readonly attempts: number;
|
|
60
|
+
readonly causeError: Error;
|
|
61
|
+
constructor(remote: string, attempts: number, causeError: Error);
|
|
62
|
+
}
|
|
63
|
+
export declare class ModuleFederationRemoteComponentContractError extends Error {
|
|
64
|
+
constructor(remote: string, exportName: string);
|
|
65
|
+
}
|
|
66
|
+
export declare function classifyModuleFederationFallback(error: unknown): ModuleFederationFallbackClassification;
|
|
67
|
+
export declare function createModuleFederationFallbackTelemetry(input: ModuleFederationFallbackTelemetryInput): ModuleFederationFallbackTelemetryPayload;
|
|
68
|
+
export declare function toModuleFederationFallbackAttributes(payload: ModuleFederationFallbackTelemetryPayload): Record<string, string>;
|
|
69
|
+
export declare function emitModuleFederationFallbackTelemetry(input: ModuleFederationFallbackTelemetryInput, options?: ModuleFederationFallbackTelemetryEmitOptions): Promise<ModuleFederationFallbackTelemetryEmitResult>;
|
|
70
|
+
/** Dispatch once locally; remote delivery is bounded and best effort. */
|
|
71
|
+
export declare function emitModuleFederationFallbackPayload(payload: ModuleFederationFallbackTelemetryPayload, options?: ModuleFederationFallbackTelemetryEmitOptions): Promise<ModuleFederationFallbackTelemetryEmitResult>;
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bleedingdev/modern-js-federation-runtime",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.3-ultramodern.2",
|
|
4
4
|
"description": "Federated surface consumption, distributed SSR, and bounded manifest recovery.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/
|
|
8
|
+
"url": "git+https://github.com/ultramodernjs/ultramodern.js.git",
|
|
9
9
|
"directory": "packages/runtime/federation-runtime"
|
|
10
10
|
},
|
|
11
11
|
"engines": {
|
|
12
|
-
"node": ">=26.
|
|
12
|
+
"node": ">=26.10.0"
|
|
13
13
|
},
|
|
14
14
|
"types": "./dist/types/module-federation/index.d.ts",
|
|
15
15
|
"main": "./dist/cjs/module-federation/index.js",
|
|
@@ -23,6 +23,22 @@
|
|
|
23
23
|
},
|
|
24
24
|
"default": "./dist/esm/module-federation/index.mjs"
|
|
25
25
|
},
|
|
26
|
+
"./renderer-contract": {
|
|
27
|
+
"types": "./dist/types/module-federation/renderer-contract.d.ts",
|
|
28
|
+
"node": {
|
|
29
|
+
"import": "./dist/esm-node/module-federation/renderer-contract.mjs",
|
|
30
|
+
"require": "./dist/cjs/module-federation/renderer-contract.js"
|
|
31
|
+
},
|
|
32
|
+
"default": "./dist/esm/module-federation/renderer-contract.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./renderer-runtime-plugin": {
|
|
35
|
+
"types": "./dist/types/module-federation/renderer-runtime-plugin.d.ts",
|
|
36
|
+
"node": {
|
|
37
|
+
"import": "./dist/esm-node/module-federation/renderer-runtime-plugin.mjs",
|
|
38
|
+
"require": "./dist/cjs/module-federation/renderer-runtime-plugin.js"
|
|
39
|
+
},
|
|
40
|
+
"default": "./dist/esm/module-federation/renderer-runtime-plugin.mjs"
|
|
41
|
+
},
|
|
26
42
|
"./distributed-ssr": {
|
|
27
43
|
"types": "./dist/types/module-federation/distributed-ssr.d.ts",
|
|
28
44
|
"node": {
|
|
@@ -46,6 +62,14 @@
|
|
|
46
62
|
"./dist/types/module-federation/index.d.ts",
|
|
47
63
|
"./src/module-federation/index.ts"
|
|
48
64
|
],
|
|
65
|
+
"renderer-contract": [
|
|
66
|
+
"./dist/types/module-federation/renderer-contract.d.ts",
|
|
67
|
+
"./src/module-federation/renderer-contract.ts"
|
|
68
|
+
],
|
|
69
|
+
"renderer-runtime-plugin": [
|
|
70
|
+
"./dist/types/module-federation/renderer-runtime-plugin.d.ts",
|
|
71
|
+
"./src/module-federation/renderer-runtime-plugin.ts"
|
|
72
|
+
],
|
|
49
73
|
"distributed-ssr": [
|
|
50
74
|
"./dist/types/module-federation/distributed-ssr.d.ts",
|
|
51
75
|
"./src/module-federation/distributed-ssr.tsx"
|
|
@@ -62,26 +86,35 @@
|
|
|
62
86
|
],
|
|
63
87
|
"sideEffects": false,
|
|
64
88
|
"dependencies": {
|
|
65
|
-
"@modern-js/
|
|
89
|
+
"@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.2",
|
|
90
|
+
"@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.3-ultramodern.2",
|
|
91
|
+
"@module-federation/sdk": "2.9.2"
|
|
66
92
|
},
|
|
67
93
|
"peerDependencies": {
|
|
68
|
-
"@modern-js/runtime": "3.9.
|
|
94
|
+
"@modern-js/runtime": "3.9.3-ultramodern.2",
|
|
69
95
|
"react": "^19.2.8"
|
|
70
96
|
},
|
|
97
|
+
"peerDependenciesMeta": {
|
|
98
|
+
"@modern-js/runtime": {
|
|
99
|
+
"optional": true
|
|
100
|
+
},
|
|
101
|
+
"react": {
|
|
102
|
+
"optional": true
|
|
103
|
+
}
|
|
104
|
+
},
|
|
71
105
|
"devDependencies": {
|
|
72
|
-
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.
|
|
73
|
-
"@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.
|
|
74
|
-
"@rsbuild/core": "2.2.
|
|
75
|
-
"@rslib/core": "1.0.
|
|
106
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.3-ultramodern.2",
|
|
107
|
+
"@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.3-ultramodern.2",
|
|
108
|
+
"@rsbuild/core": "2.2.11",
|
|
109
|
+
"@rslib/core": "1.0.3",
|
|
76
110
|
"@scripts/rstest-config": "2.66.0",
|
|
77
|
-
"@types/node": "^26.
|
|
78
|
-
"@types/react": "^19.
|
|
79
|
-
"@types/react-dom": "^19.
|
|
80
|
-
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
111
|
+
"@types/node": "^26.6.3",
|
|
112
|
+
"@types/react": "^19.3.0",
|
|
113
|
+
"@types/react-dom": "^19.3.0",
|
|
81
114
|
"esbuild": "^0.28.2",
|
|
82
|
-
"react": "^19.
|
|
83
|
-
"react-dom": "^19.
|
|
84
|
-
"typescript": "
|
|
115
|
+
"react": "^19.3.0",
|
|
116
|
+
"react-dom": "^19.3.0",
|
|
117
|
+
"typescript": "7.0.2"
|
|
85
118
|
},
|
|
86
119
|
"publishConfig": {
|
|
87
120
|
"access": "public"
|
|
@@ -91,8 +124,11 @@
|
|
|
91
124
|
"build": "rslib build",
|
|
92
125
|
"test": "rstest run"
|
|
93
126
|
},
|
|
94
|
-
"homepage": "https://github.com/
|
|
127
|
+
"homepage": "https://github.com/ultramodernjs/ultramodern.js#readme",
|
|
95
128
|
"bugs": {
|
|
96
|
-
"url": "https://github.com/
|
|
129
|
+
"url": "https://github.com/ultramodernjs/ultramodern.js/issues"
|
|
130
|
+
},
|
|
131
|
+
"ultramodern": {
|
|
132
|
+
"sourceName": "@modern-js/federation-runtime"
|
|
97
133
|
}
|
|
98
134
|
}
|
|
@@ -23,14 +23,7 @@
|
|
|
23
23
|
* consumption during a rollout window should be driven by expand/contract, not
|
|
24
24
|
* by silent degrade.
|
|
25
25
|
*/
|
|
26
|
-
|
|
27
|
-
classifyModuleFederationFallback,
|
|
28
|
-
createModuleFederationFallbackTelemetry,
|
|
29
|
-
emitModuleFederationFallbackTelemetry,
|
|
30
|
-
type ModuleFederationFallbackClassification,
|
|
31
|
-
type ModuleFederationFallbackTelemetryEmitOptions,
|
|
32
|
-
type ModuleFederationFallbackTelemetryPayload,
|
|
33
|
-
} from './index';
|
|
26
|
+
|
|
34
27
|
import {
|
|
35
28
|
createDiscoveryError,
|
|
36
29
|
type DiscoveryError,
|
|
@@ -44,6 +37,15 @@ import {
|
|
|
44
37
|
type SurfaceResolutionProvider,
|
|
45
38
|
validateSurfaceRef,
|
|
46
39
|
} from './surface-resolution-types';
|
|
40
|
+
import {
|
|
41
|
+
classifyModuleFederationFallback,
|
|
42
|
+
createModuleFederationFallbackTelemetry,
|
|
43
|
+
emitModuleFederationFallbackPayload,
|
|
44
|
+
emitModuleFederationFallbackTelemetry,
|
|
45
|
+
type ModuleFederationFallbackClassification,
|
|
46
|
+
type ModuleFederationFallbackTelemetryEmitOptions,
|
|
47
|
+
type ModuleFederationFallbackTelemetryPayload,
|
|
48
|
+
} from './telemetry';
|
|
47
49
|
|
|
48
50
|
/** Where in the consumption lifecycle a failure was raised. */
|
|
49
51
|
export type SurfaceConsumptionPhase = 'discovery' | 'load' | 'mount';
|
|
@@ -100,7 +102,7 @@ export type SurfaceConsumerOptions<T> = {
|
|
|
100
102
|
* omitted.
|
|
101
103
|
*
|
|
102
104
|
* - `'noncritical'`: the degraded handler's result is returned and the
|
|
103
|
-
* failure is swallowed —
|
|
105
|
+
* failure is swallowed — a failed degraded handler resolves undefined.
|
|
104
106
|
* - `'critical'`: the degraded handler still runs (telemetry + fallback-UI
|
|
105
107
|
* obligations hold), but the returned promise then REJECTS with the typed
|
|
106
108
|
* failure so callers / rollout machinery observe it. Prefer expand/contract
|
|
@@ -154,7 +156,7 @@ async function reportFailure<T>(
|
|
|
154
156
|
error?: unknown;
|
|
155
157
|
resolved?: ResolvedDeliveryUnit;
|
|
156
158
|
},
|
|
157
|
-
): Promise<T> {
|
|
159
|
+
): Promise<T | undefined> {
|
|
158
160
|
const remote = toRemoteString(ref);
|
|
159
161
|
const telemetry = createModuleFederationFallbackTelemetry({
|
|
160
162
|
appName: options.appName,
|
|
@@ -173,24 +175,7 @@ async function reportFailure<T>(
|
|
|
173
175
|
status: 'degraded',
|
|
174
176
|
});
|
|
175
177
|
|
|
176
|
-
|
|
177
|
-
// failures must never mask the degraded path.
|
|
178
|
-
try {
|
|
179
|
-
await emitModuleFederationFallbackTelemetry(
|
|
180
|
-
{
|
|
181
|
-
appName: options.appName,
|
|
182
|
-
classification: base.classification,
|
|
183
|
-
error: base.error ?? base.discoveryError,
|
|
184
|
-
metadata: telemetry.metadata,
|
|
185
|
-
phase: base.phase,
|
|
186
|
-
remote,
|
|
187
|
-
status: 'degraded',
|
|
188
|
-
},
|
|
189
|
-
options.telemetry ?? {},
|
|
190
|
-
);
|
|
191
|
-
} catch {
|
|
192
|
-
// Telemetry sink failure is itself a degraded condition; swallow it.
|
|
193
|
-
}
|
|
178
|
+
void emitModuleFederationFallbackPayload(telemetry, options.telemetry);
|
|
194
179
|
|
|
195
180
|
const failure: SurfaceConsumptionFailure = {
|
|
196
181
|
ref,
|
|
@@ -234,7 +219,7 @@ async function reportFailure<T>(
|
|
|
234
219
|
// telemetry, then for noncritical resolve undefined; for critical reject
|
|
235
220
|
// with the ORIGINAL typed error (never the handler's).
|
|
236
221
|
try {
|
|
237
|
-
|
|
222
|
+
void emitModuleFederationFallbackTelemetry(
|
|
238
223
|
{
|
|
239
224
|
appName: options.appName,
|
|
240
225
|
classification: base.classification,
|
|
@@ -252,7 +237,7 @@ async function reportFailure<T>(
|
|
|
252
237
|
if (critical) {
|
|
253
238
|
throw reason;
|
|
254
239
|
}
|
|
255
|
-
return undefined
|
|
240
|
+
return undefined;
|
|
256
241
|
}
|
|
257
242
|
|
|
258
243
|
if (critical) {
|
|
@@ -266,14 +251,14 @@ async function reportFailure<T>(
|
|
|
266
251
|
* load failure the required degraded handler runs (telemetry + fallback UI).
|
|
267
252
|
*
|
|
268
253
|
* For a `noncritical` consumption (see {@link SurfaceConsumerOptions.classification})
|
|
269
|
-
* this resolves to the degraded value
|
|
254
|
+
* this resolves to the degraded value (or undefined if the handler fails), so a failing
|
|
270
255
|
* consumption is isolated from any sibling. For a `critical` consumption (the
|
|
271
256
|
* default) it rejects with the typed failure AFTER the degraded handler has
|
|
272
257
|
* run, so callers / rollout machinery observe the failure.
|
|
273
258
|
*/
|
|
274
259
|
export async function consumeSurface<T>(
|
|
275
260
|
options: SurfaceConsumerOptions<T>,
|
|
276
|
-
): Promise<T> {
|
|
261
|
+
): Promise<T | undefined> {
|
|
277
262
|
let ref: ParsedSurfaceRef;
|
|
278
263
|
if (typeof options.ref === 'string') {
|
|
279
264
|
const parsed = parseSurfaceRef(options.ref);
|
|
@@ -360,7 +345,7 @@ export function createSurfaceConsumer(
|
|
|
360
345
|
return function consume<T>(
|
|
361
346
|
options: Omit<SurfaceConsumerOptions<T>, keyof typeof base> &
|
|
362
347
|
Partial<Pick<SurfaceConsumerOptions<T>, keyof typeof base>>,
|
|
363
|
-
): Promise<T> {
|
|
348
|
+
): Promise<T | undefined> {
|
|
364
349
|
return consumeSurface<T>({
|
|
365
350
|
...base,
|
|
366
351
|
...options,
|
|
@@ -51,8 +51,28 @@ export type DistributedSsrBoundaryProps<
|
|
|
51
51
|
remote: string;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* The Module Federation `createLazyComponent` options the distributed boundary
|
|
56
|
+
* owns. `injectLink` is always false: the boundary owns remote CSS (the
|
|
57
|
+
* fragment CSS inventory in workerd, the MF manifest in the browser), so the
|
|
58
|
+
* bridge must not render a second `<link>` in SSR HTML.
|
|
59
|
+
*/
|
|
60
|
+
export type DistributedSsrLazyComponentOptions = {
|
|
61
|
+
export: 'default';
|
|
62
|
+
fallback: ReactNode;
|
|
63
|
+
injectLink: false;
|
|
64
|
+
loading: null;
|
|
65
|
+
};
|
|
66
|
+
|
|
54
67
|
export type CreateDistributedSsrComponentOptions<Props extends object> = {
|
|
55
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Creates the native remote on first render. Spread `options` into
|
|
70
|
+
* Module Federation's `createLazyComponent` and add the instance and
|
|
71
|
+
* loader.
|
|
72
|
+
*/
|
|
73
|
+
createComponent: (
|
|
74
|
+
options: DistributedSsrLazyComponentOptions,
|
|
75
|
+
) => ComponentType<Props>;
|
|
56
76
|
expose: string;
|
|
57
77
|
fallback: ReactNode;
|
|
58
78
|
remote: string;
|
|
@@ -221,7 +241,12 @@ export function createDistributedSsrComponent<Props extends object>({
|
|
|
221
241
|
let RemoteComponent: ComponentType<Props> | undefined;
|
|
222
242
|
|
|
223
243
|
function DeferredRemoteComponent(props: Props) {
|
|
224
|
-
RemoteComponent ??= createComponent(
|
|
244
|
+
RemoteComponent ??= createComponent({
|
|
245
|
+
export: 'default',
|
|
246
|
+
fallback,
|
|
247
|
+
injectLink: false,
|
|
248
|
+
loading: null,
|
|
249
|
+
});
|
|
225
250
|
return <RemoteComponent {...props} />;
|
|
226
251
|
}
|
|
227
252
|
|