@module-federation/bridge-react 0.0.0-docs-remove-invalid-lark-link-20251205062649
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/CHANGELOG.md +728 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/__tests__/bridge.spec.tsx +160 -0
- package/__tests__/createLazyComponent.spec.tsx +209 -0
- package/__tests__/prefetch.spec.ts +156 -0
- package/__tests__/router.spec.tsx +82 -0
- package/__tests__/setupTests.ts +8 -0
- package/__tests__/util.ts +36 -0
- package/dist/base.cjs.js +29 -0
- package/dist/base.d.ts +311 -0
- package/dist/base.es.js +30 -0
- package/dist/bridge-base-CPSTBjEp.mjs +211 -0
- package/dist/bridge-base-RStDxH71.js +226 -0
- package/dist/createHelpers-B_L612IN.js +190 -0
- package/dist/createHelpers-Ui5pt7je.mjs +191 -0
- package/dist/data-fetch-server-middleware.cjs.js +163 -0
- package/dist/data-fetch-server-middleware.d.ts +15 -0
- package/dist/data-fetch-server-middleware.es.js +164 -0
- package/dist/data-fetch-utils.cjs.js +24 -0
- package/dist/data-fetch-utils.d.ts +81 -0
- package/dist/data-fetch-utils.es.js +26 -0
- package/dist/index-DRSBaSu3.js +45 -0
- package/dist/index-DyQNwY2M.mjs +46 -0
- package/dist/index.cjs.js +125 -0
- package/dist/index.d.ts +299 -0
- package/dist/index.es.js +109 -0
- package/dist/index.esm-BWaKho-8.js +491 -0
- package/dist/index.esm-CPwSeCvw.mjs +492 -0
- package/dist/lazy-load-component-plugin-CSRkMmKF.js +521 -0
- package/dist/lazy-load-component-plugin-DXqhuywC.mjs +522 -0
- package/dist/lazy-load-component-plugin.cjs.js +6 -0
- package/dist/lazy-load-component-plugin.d.ts +16 -0
- package/dist/lazy-load-component-plugin.es.js +6 -0
- package/dist/lazy-utils.cjs.js +24 -0
- package/dist/lazy-utils.d.ts +149 -0
- package/dist/lazy-utils.es.js +24 -0
- package/dist/plugin.cjs.js +14 -0
- package/dist/plugin.d.ts +22 -0
- package/dist/plugin.es.js +14 -0
- package/dist/prefetch-A3QkU5oZ.js +1272 -0
- package/dist/prefetch-zMJL79zx.mjs +1273 -0
- package/dist/router-v5.cjs.js +55 -0
- package/dist/router-v5.d.ts +18 -0
- package/dist/router-v5.es.js +32 -0
- package/dist/router-v6.cjs.js +84 -0
- package/dist/router-v6.d.ts +20 -0
- package/dist/router-v6.es.js +61 -0
- package/dist/router-v7.cjs.js +83 -0
- package/dist/router-v7.d.ts +20 -0
- package/dist/router-v7.es.js +61 -0
- package/dist/router.cjs.js +82 -0
- package/dist/router.d.ts +20 -0
- package/dist/router.es.js +60 -0
- package/dist/utils-dUgb9Jkm.mjs +2016 -0
- package/dist/utils-tM9yE73c.js +2015 -0
- package/dist/v18.cjs.js +15 -0
- package/dist/v18.d.ts +114 -0
- package/dist/v18.es.js +15 -0
- package/dist/v19.cjs.js +15 -0
- package/dist/v19.d.ts +115 -0
- package/dist/v19.es.js +15 -0
- package/jest.config.ts +21 -0
- package/package.json +173 -0
- package/project.json +23 -0
- package/src/base.ts +50 -0
- package/src/index.ts +50 -0
- package/src/lazy/AwaitDataFetch.tsx +215 -0
- package/src/lazy/constant.ts +30 -0
- package/src/lazy/createLazyComponent.tsx +411 -0
- package/src/lazy/data-fetch/cache.ts +291 -0
- package/src/lazy/data-fetch/call-data-fetch.ts +13 -0
- package/src/lazy/data-fetch/data-fetch-server-middleware.ts +196 -0
- package/src/lazy/data-fetch/index.ts +16 -0
- package/src/lazy/data-fetch/inject-data-fetch.ts +109 -0
- package/src/lazy/data-fetch/prefetch.ts +112 -0
- package/src/lazy/data-fetch/runtime-plugin.ts +115 -0
- package/src/lazy/index.ts +35 -0
- package/src/lazy/logger.ts +6 -0
- package/src/lazy/types.ts +75 -0
- package/src/lazy/utils.ts +372 -0
- package/src/lazy/wrapNoSSR.tsx +10 -0
- package/src/modern-app-env.d.ts +2 -0
- package/src/plugins/lazy-load-component-plugin.spec.ts +21 -0
- package/src/plugins/lazy-load-component-plugin.ts +57 -0
- package/src/provider/context.tsx +4 -0
- package/src/provider/plugin.ts +22 -0
- package/src/provider/versions/bridge-base.tsx +150 -0
- package/src/provider/versions/legacy.ts +87 -0
- package/src/provider/versions/v18.ts +47 -0
- package/src/provider/versions/v19.ts +48 -0
- package/src/remote/RemoteAppWrapper.tsx +108 -0
- package/src/remote/base-component/component.tsx +2 -0
- package/src/remote/base-component/create.tsx +23 -0
- package/src/remote/base-component/index.tsx +10 -0
- package/src/remote/createHelpers.tsx +130 -0
- package/src/remote/router-component/component.tsx +104 -0
- package/src/remote/router-component/create.tsx +23 -0
- package/src/remote/router-component/index.tsx +10 -0
- package/src/router/default.tsx +73 -0
- package/src/router/v5.tsx +43 -0
- package/src/router/v6.tsx +74 -0
- package/src/router/v7.tsx +75 -0
- package/src/types.ts +147 -0
- package/src/utils/index.ts +44 -0
- package/src/v18.ts +9 -0
- package/src/v19.ts +9 -0
- package/tsconfig.json +42 -0
- package/tsconfig.node.json +11 -0
- package/tsconfig.spec.json +26 -0
- package/vite.config.ts +112 -0
- package/vitest.config.ts +27 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { c as createBaseBridgeComponent, E as ErrorBoundary } from "./bridge-base-CPSTBjEp.mjs";
|
|
2
|
+
import ReactDOM from "react-dom";
|
|
3
|
+
import { L as LoggerInstance, g as getRootDomDefaultClassName } from "./index-DyQNwY2M.mjs";
|
|
4
|
+
import React__default, { forwardRef, useRef, useState, useEffect } from "react";
|
|
5
|
+
import { federationRuntime } from "./plugin.es.js";
|
|
6
|
+
function createReact16Or17Root(container) {
|
|
7
|
+
return {
|
|
8
|
+
render(children) {
|
|
9
|
+
const reactVersion = ReactDOM.version || "";
|
|
10
|
+
const isReact18 = reactVersion.startsWith("18");
|
|
11
|
+
const isReact19 = reactVersion.startsWith("19");
|
|
12
|
+
if (isReact19) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`React 19 detected in legacy mode. This is not supported. Please use the version-specific import: import { createBridgeComponent } from '@module-federation/bridge-react/v19'`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (isReact18) {
|
|
18
|
+
LoggerInstance.warn(
|
|
19
|
+
`[Bridge-React] React 18 detected in legacy mode. For better compatibility, please use the version-specific import: import { createBridgeComponent } from '@module-federation/bridge-react/v18'`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
ReactDOM.render(children, container);
|
|
23
|
+
},
|
|
24
|
+
unmount() {
|
|
25
|
+
ReactDOM.unmountComponentAtNode(container);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function createBridgeComponent(bridgeInfo) {
|
|
30
|
+
const fullBridgeInfo = {
|
|
31
|
+
createRoot: createReact16Or17Root,
|
|
32
|
+
...bridgeInfo
|
|
33
|
+
};
|
|
34
|
+
return createBaseBridgeComponent(fullBridgeInfo);
|
|
35
|
+
}
|
|
36
|
+
const RemoteAppWrapper = forwardRef(function(props, ref) {
|
|
37
|
+
const {
|
|
38
|
+
moduleName,
|
|
39
|
+
memoryRoute,
|
|
40
|
+
basename,
|
|
41
|
+
providerInfo,
|
|
42
|
+
className,
|
|
43
|
+
style,
|
|
44
|
+
fallback,
|
|
45
|
+
loading,
|
|
46
|
+
...resProps
|
|
47
|
+
} = props;
|
|
48
|
+
const instance = federationRuntime.instance;
|
|
49
|
+
const rootRef = ref && "current" in ref ? ref : useRef(null);
|
|
50
|
+
const renderDom = useRef(null);
|
|
51
|
+
const providerInfoRef = useRef(null);
|
|
52
|
+
const [initialized, setInitialized] = useState(false);
|
|
53
|
+
LoggerInstance.debug(`RemoteAppWrapper instance from props >>>`, instance);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (initialized) return;
|
|
56
|
+
const providerReturn = providerInfo();
|
|
57
|
+
providerInfoRef.current = providerReturn;
|
|
58
|
+
setInitialized(true);
|
|
59
|
+
return () => {
|
|
60
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
61
|
+
if ((_a = providerInfoRef.current) == null ? void 0 : _a.destroy) {
|
|
62
|
+
LoggerInstance.debug(
|
|
63
|
+
`createRemoteAppComponent LazyComponent destroy >>>`,
|
|
64
|
+
{ moduleName, basename, dom: renderDom.current }
|
|
65
|
+
);
|
|
66
|
+
(_d = (_c = (_b = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _b.lifecycle) == null ? void 0 : _c.beforeBridgeDestroy) == null ? void 0 : _d.emit({
|
|
67
|
+
moduleName,
|
|
68
|
+
dom: renderDom.current,
|
|
69
|
+
basename,
|
|
70
|
+
memoryRoute,
|
|
71
|
+
fallback,
|
|
72
|
+
...resProps
|
|
73
|
+
});
|
|
74
|
+
(_e = providerInfoRef.current) == null ? void 0 : _e.destroy({
|
|
75
|
+
moduleName,
|
|
76
|
+
dom: renderDom.current
|
|
77
|
+
});
|
|
78
|
+
(_h = (_g = (_f = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _f.lifecycle) == null ? void 0 : _g.afterBridgeDestroy) == null ? void 0 : _h.emit({
|
|
79
|
+
moduleName,
|
|
80
|
+
dom: renderDom.current,
|
|
81
|
+
basename,
|
|
82
|
+
memoryRoute,
|
|
83
|
+
fallback,
|
|
84
|
+
...resProps
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}, [moduleName]);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
var _a, _b, _c, _d, _e, _f;
|
|
91
|
+
if (!initialized || !providerInfoRef.current) return;
|
|
92
|
+
let renderProps = {
|
|
93
|
+
moduleName,
|
|
94
|
+
dom: rootRef.current,
|
|
95
|
+
basename,
|
|
96
|
+
memoryRoute,
|
|
97
|
+
fallback,
|
|
98
|
+
...resProps
|
|
99
|
+
};
|
|
100
|
+
renderDom.current = rootRef.current;
|
|
101
|
+
const beforeBridgeRenderRes = ((_c = (_b = (_a = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _a.lifecycle) == null ? void 0 : _b.beforeBridgeRender) == null ? void 0 : _c.emit(renderProps)) || {};
|
|
102
|
+
renderProps = { ...renderProps, ...beforeBridgeRenderRes.extraProps };
|
|
103
|
+
providerInfoRef.current.render(renderProps);
|
|
104
|
+
(_f = (_e = (_d = instance == null ? void 0 : instance.bridgeHook) == null ? void 0 : _d.lifecycle) == null ? void 0 : _e.afterBridgeRender) == null ? void 0 : _f.emit(renderProps);
|
|
105
|
+
}, [initialized, ...Object.values(props)]);
|
|
106
|
+
const rootComponentClassName = `${getRootDomDefaultClassName(moduleName)} ${className || ""}`;
|
|
107
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: rootComponentClassName, style, ref: rootRef }, loading);
|
|
108
|
+
});
|
|
109
|
+
function createLazyRemoteComponentFactory(RemoteApp) {
|
|
110
|
+
return function createLazyRemoteComponent(info) {
|
|
111
|
+
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
112
|
+
return React__default.lazy(async () => {
|
|
113
|
+
LoggerInstance.debug(
|
|
114
|
+
`createRemoteAppComponent LazyComponent create >>>`,
|
|
115
|
+
{
|
|
116
|
+
lazyComponent: info.loader,
|
|
117
|
+
exportName
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
try {
|
|
121
|
+
const m = await info.loader();
|
|
122
|
+
const moduleName = m && m[Symbol.for("mf_module_id")];
|
|
123
|
+
LoggerInstance.debug(
|
|
124
|
+
`createRemoteAppComponent LazyComponent loadRemote info >>>`,
|
|
125
|
+
{ name: moduleName, module: m, exportName }
|
|
126
|
+
);
|
|
127
|
+
const exportFn = m[exportName];
|
|
128
|
+
if (exportName in m && typeof exportFn === "function") {
|
|
129
|
+
const RemoteAppComponent = forwardRef((props, ref) => {
|
|
130
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
131
|
+
RemoteApp,
|
|
132
|
+
{
|
|
133
|
+
moduleName,
|
|
134
|
+
providerInfo: exportFn,
|
|
135
|
+
exportName: info.export || "default",
|
|
136
|
+
fallback: info.fallback,
|
|
137
|
+
loading: info.loading,
|
|
138
|
+
ref,
|
|
139
|
+
...props
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
default: RemoteAppComponent
|
|
145
|
+
};
|
|
146
|
+
} else {
|
|
147
|
+
LoggerInstance.debug(
|
|
148
|
+
`createRemoteAppComponent LazyComponent module not found >>>`,
|
|
149
|
+
{ name: moduleName, module: m, exportName }
|
|
150
|
+
);
|
|
151
|
+
throw Error(
|
|
152
|
+
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
153
|
+
exportName
|
|
154
|
+
)}`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
} catch (error) {
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function createRemoteAppComponentFactory(RemoteApp) {
|
|
164
|
+
const createLazyRemoteComponent = createLazyRemoteComponentFactory(RemoteApp);
|
|
165
|
+
return function createRemoteAppComponent(info) {
|
|
166
|
+
const LazyComponent = createLazyRemoteComponent(info);
|
|
167
|
+
return forwardRef((props, ref) => {
|
|
168
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
169
|
+
ErrorBoundary,
|
|
170
|
+
{
|
|
171
|
+
FallbackComponent: info.fallback
|
|
172
|
+
},
|
|
173
|
+
/* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: info.loading }, /* @__PURE__ */ React__default.createElement(LazyComponent, { ...props, ref }))
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function createDeprecatedRemoteComponentFactory(createFn) {
|
|
179
|
+
return function createRemoteComponent(info) {
|
|
180
|
+
LoggerInstance.warn(
|
|
181
|
+
`createRemoteComponent is deprecated, please use createRemoteAppComponent instead!`
|
|
182
|
+
);
|
|
183
|
+
return createFn(info);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export {
|
|
187
|
+
RemoteAppWrapper as R,
|
|
188
|
+
createRemoteAppComponentFactory as a,
|
|
189
|
+
createBridgeComponent as b,
|
|
190
|
+
createDeprecatedRemoteComponentFactory as c
|
|
191
|
+
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const lazyUtils = require("./utils-tM9yE73c.js");
|
|
3
|
+
const index_esm = require("./index.esm-BWaKho-8.js");
|
|
4
|
+
function wrapSetTimeout(targetPromise, delay = 2e4, id) {
|
|
5
|
+
if (targetPromise && typeof targetPromise.then === "function") {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const timeoutId = setTimeout(() => {
|
|
8
|
+
lazyUtils.logger.warn(`Data fetch for ID ${id} timed out after 20 seconds.`);
|
|
9
|
+
reject(new Error(`Data fetch for ID ${id} timed out after 20 seconds`));
|
|
10
|
+
}, delay);
|
|
11
|
+
targetPromise.then((value) => {
|
|
12
|
+
clearTimeout(timeoutId);
|
|
13
|
+
resolve(value);
|
|
14
|
+
}).catch((err) => {
|
|
15
|
+
clearTimeout(timeoutId);
|
|
16
|
+
reject(err);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function addProtocol(url) {
|
|
22
|
+
if (url.startsWith("//")) {
|
|
23
|
+
return "https:" + url;
|
|
24
|
+
}
|
|
25
|
+
return url;
|
|
26
|
+
}
|
|
27
|
+
const getDecodeQuery = (url, name) => {
|
|
28
|
+
const res = url.searchParams.get(name);
|
|
29
|
+
if (!res) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return decodeURIComponent(res);
|
|
33
|
+
};
|
|
34
|
+
const dataFetchServerMiddleware = async (ctx, next) => {
|
|
35
|
+
var _a, _b, _c;
|
|
36
|
+
let url;
|
|
37
|
+
let dataFetchKey;
|
|
38
|
+
let params;
|
|
39
|
+
let remoteInfo;
|
|
40
|
+
try {
|
|
41
|
+
url = new URL(ctx.req.url);
|
|
42
|
+
dataFetchKey = getDecodeQuery(url, lazyUtils.DATA_FETCH_QUERY);
|
|
43
|
+
params = JSON.parse(getDecodeQuery(url, "params") || "{}");
|
|
44
|
+
const remoteInfoQuery = getDecodeQuery(url, "remoteInfo");
|
|
45
|
+
remoteInfo = remoteInfoQuery ? JSON.parse(remoteInfoQuery) : null;
|
|
46
|
+
} catch (e) {
|
|
47
|
+
lazyUtils.logger.error("fetch data from server, error: ", e);
|
|
48
|
+
return next();
|
|
49
|
+
}
|
|
50
|
+
if (!dataFetchKey) {
|
|
51
|
+
return next();
|
|
52
|
+
}
|
|
53
|
+
lazyUtils.logger.log("fetch data from server, dataFetchKey: ", dataFetchKey);
|
|
54
|
+
lazyUtils.logger.debug(
|
|
55
|
+
"fetch data from server, moduleInfo: ",
|
|
56
|
+
(_a = globalThis.__FEDERATION__) == null ? void 0 : _a.moduleInfo
|
|
57
|
+
);
|
|
58
|
+
try {
|
|
59
|
+
const dataFetchMap = lazyUtils.getDataFetchMap();
|
|
60
|
+
if (!dataFetchMap) {
|
|
61
|
+
lazyUtils.initDataFetchMap();
|
|
62
|
+
}
|
|
63
|
+
const fetchDataPromise = (_b = dataFetchMap[dataFetchKey]) == null ? void 0 : _b[1];
|
|
64
|
+
lazyUtils.logger.debug(
|
|
65
|
+
"fetch data from server, fetchDataPromise: ",
|
|
66
|
+
fetchDataPromise
|
|
67
|
+
);
|
|
68
|
+
if (fetchDataPromise && ((_c = dataFetchMap[dataFetchKey]) == null ? void 0 : _c[2]) !== lazyUtils.MF_DATA_FETCH_STATUS.ERROR) {
|
|
69
|
+
const targetPromise = fetchDataPromise[0];
|
|
70
|
+
const wrappedPromise = wrapSetTimeout(targetPromise, 2e4, dataFetchKey);
|
|
71
|
+
if (wrappedPromise) {
|
|
72
|
+
const res = await wrappedPromise;
|
|
73
|
+
lazyUtils.logger.log("fetch data from server, fetchDataPromise res: ", res);
|
|
74
|
+
return ctx.json(res);
|
|
75
|
+
}
|
|
76
|
+
lazyUtils.logger.error(
|
|
77
|
+
`Expected a Promise from fetchDataPromise[0] for dataFetchKey ${dataFetchKey}, but received:`,
|
|
78
|
+
targetPromise,
|
|
79
|
+
"Will try call new dataFetch again..."
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (remoteInfo) {
|
|
83
|
+
try {
|
|
84
|
+
const hostInstance2 = globalThis.__FEDERATION__.__INSTANCES__[0];
|
|
85
|
+
const remoteEntry = `${addProtocol(remoteInfo.ssrPublicPath) + remoteInfo.ssrRemoteEntry}`;
|
|
86
|
+
if (!hostInstance2) {
|
|
87
|
+
throw new Error("host instance not found!");
|
|
88
|
+
}
|
|
89
|
+
const remote = hostInstance2.options.remotes.find(
|
|
90
|
+
(remote2) => remote2.name === remoteInfo.name
|
|
91
|
+
);
|
|
92
|
+
lazyUtils.logger.debug("find remote: ", JSON.stringify(remote));
|
|
93
|
+
if (!remote) {
|
|
94
|
+
hostInstance2.registerRemotes([
|
|
95
|
+
{
|
|
96
|
+
name: remoteInfo.name,
|
|
97
|
+
entry: remoteEntry,
|
|
98
|
+
entryGlobalName: remoteInfo.globalName
|
|
99
|
+
}
|
|
100
|
+
]);
|
|
101
|
+
} else if (!("entry" in remote) || !remote.entry.includes(index_esm.MANIFEST_EXT)) {
|
|
102
|
+
const { hostGlobalSnapshot, remoteSnapshot } = hostInstance2.snapshotHandler.getGlobalRemoteInfo(remoteInfo);
|
|
103
|
+
lazyUtils.logger.debug(
|
|
104
|
+
"find hostGlobalSnapshot: ",
|
|
105
|
+
JSON.stringify(hostGlobalSnapshot)
|
|
106
|
+
);
|
|
107
|
+
lazyUtils.logger.debug("find remoteSnapshot: ", JSON.stringify(remoteSnapshot));
|
|
108
|
+
if (!hostGlobalSnapshot || !remoteSnapshot) {
|
|
109
|
+
if ("version" in remote) {
|
|
110
|
+
delete remote.version;
|
|
111
|
+
}
|
|
112
|
+
remote.entry = remoteEntry;
|
|
113
|
+
remote.entryGlobalName = remoteInfo.globalName;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} catch (e) {
|
|
117
|
+
ctx.status(500);
|
|
118
|
+
return ctx.text(
|
|
119
|
+
`failed to fetch ${remoteInfo.name} data, error:
|
|
120
|
+
${e}`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const dataFetchItem = dataFetchMap[dataFetchKey];
|
|
125
|
+
lazyUtils.logger.debug("fetch data from server, dataFetchItem: ", dataFetchItem);
|
|
126
|
+
if (dataFetchItem) {
|
|
127
|
+
const callFetchDataPromise = lazyUtils.fetchData(dataFetchKey, {
|
|
128
|
+
...params,
|
|
129
|
+
isDowngrade: !remoteInfo,
|
|
130
|
+
_id: dataFetchKey
|
|
131
|
+
});
|
|
132
|
+
const wrappedPromise = wrapSetTimeout(
|
|
133
|
+
callFetchDataPromise,
|
|
134
|
+
2e4,
|
|
135
|
+
dataFetchKey
|
|
136
|
+
);
|
|
137
|
+
if (wrappedPromise) {
|
|
138
|
+
const res = await wrappedPromise;
|
|
139
|
+
lazyUtils.logger.log("fetch data from server, dataFetchItem res: ", res);
|
|
140
|
+
return ctx.json(res);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const remoteId = dataFetchKey.split(index_esm.SEPARATOR)[0];
|
|
144
|
+
const hostInstance = globalThis.__FEDERATION__.__INSTANCES__[0];
|
|
145
|
+
if (!hostInstance) {
|
|
146
|
+
throw new Error("host instance not found!");
|
|
147
|
+
}
|
|
148
|
+
const dataFetchFn = await lazyUtils.loadDataFetchModule(hostInstance, remoteId);
|
|
149
|
+
const data = await dataFetchFn({
|
|
150
|
+
...params,
|
|
151
|
+
isDowngrade: !remoteInfo,
|
|
152
|
+
_id: dataFetchKey
|
|
153
|
+
});
|
|
154
|
+
lazyUtils.logger.log("fetch data from server, loadDataFetchModule res: ", data);
|
|
155
|
+
return ctx.json(data);
|
|
156
|
+
} catch (e) {
|
|
157
|
+
lazyUtils.logger.error("server plugin data fetch error: ", e);
|
|
158
|
+
ctx.status(500);
|
|
159
|
+
return ctx.text(`failed to fetch ${remoteInfo.name} data, error:
|
|
160
|
+
${e}`);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
module.exports = dataFetchServerMiddleware;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MiddlewareHandler } from 'hono';
|
|
2
|
+
|
|
3
|
+
declare const dataFetchServerMiddleware: MiddlewareHandler;
|
|
4
|
+
export default dataFetchServerMiddleware;
|
|
5
|
+
|
|
6
|
+
export { }
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
declare module '@module-federation/runtime-core' {
|
|
10
|
+
interface ModuleFederation {
|
|
11
|
+
createLazyComponent<T, E extends keyof T>(options: Omit<CreateLazyComponentOptions<T, E>, 'instance'>): ReturnType<typeof createLazyComponent<T, E>>;
|
|
12
|
+
prefetch(options: Omit<PrefetchOptions, 'instance'>): ReturnType<typeof prefetch>;
|
|
13
|
+
collectSSRAssets(options: Omit<Parameters<typeof collectSSRAssets>[0], 'instance'>): ReturnType<typeof collectSSRAssets>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { D as DATA_FETCH_QUERY, l as logger, e as getDataFetchMap, i as initDataFetchMap, M as MF_DATA_FETCH_STATUS, f as fetchData, h as loadDataFetchModule } from "./utils-dUgb9Jkm.mjs";
|
|
2
|
+
import { M as MANIFEST_EXT, S as SEPARATOR } from "./index.esm-CPwSeCvw.mjs";
|
|
3
|
+
function wrapSetTimeout(targetPromise, delay = 2e4, id) {
|
|
4
|
+
if (targetPromise && typeof targetPromise.then === "function") {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const timeoutId = setTimeout(() => {
|
|
7
|
+
logger.warn(`Data fetch for ID ${id} timed out after 20 seconds.`);
|
|
8
|
+
reject(new Error(`Data fetch for ID ${id} timed out after 20 seconds`));
|
|
9
|
+
}, delay);
|
|
10
|
+
targetPromise.then((value) => {
|
|
11
|
+
clearTimeout(timeoutId);
|
|
12
|
+
resolve(value);
|
|
13
|
+
}).catch((err) => {
|
|
14
|
+
clearTimeout(timeoutId);
|
|
15
|
+
reject(err);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function addProtocol(url) {
|
|
21
|
+
if (url.startsWith("//")) {
|
|
22
|
+
return "https:" + url;
|
|
23
|
+
}
|
|
24
|
+
return url;
|
|
25
|
+
}
|
|
26
|
+
const getDecodeQuery = (url, name) => {
|
|
27
|
+
const res = url.searchParams.get(name);
|
|
28
|
+
if (!res) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return decodeURIComponent(res);
|
|
32
|
+
};
|
|
33
|
+
const dataFetchServerMiddleware = async (ctx, next) => {
|
|
34
|
+
var _a, _b, _c;
|
|
35
|
+
let url;
|
|
36
|
+
let dataFetchKey;
|
|
37
|
+
let params;
|
|
38
|
+
let remoteInfo;
|
|
39
|
+
try {
|
|
40
|
+
url = new URL(ctx.req.url);
|
|
41
|
+
dataFetchKey = getDecodeQuery(url, DATA_FETCH_QUERY);
|
|
42
|
+
params = JSON.parse(getDecodeQuery(url, "params") || "{}");
|
|
43
|
+
const remoteInfoQuery = getDecodeQuery(url, "remoteInfo");
|
|
44
|
+
remoteInfo = remoteInfoQuery ? JSON.parse(remoteInfoQuery) : null;
|
|
45
|
+
} catch (e) {
|
|
46
|
+
logger.error("fetch data from server, error: ", e);
|
|
47
|
+
return next();
|
|
48
|
+
}
|
|
49
|
+
if (!dataFetchKey) {
|
|
50
|
+
return next();
|
|
51
|
+
}
|
|
52
|
+
logger.log("fetch data from server, dataFetchKey: ", dataFetchKey);
|
|
53
|
+
logger.debug(
|
|
54
|
+
"fetch data from server, moduleInfo: ",
|
|
55
|
+
(_a = globalThis.__FEDERATION__) == null ? void 0 : _a.moduleInfo
|
|
56
|
+
);
|
|
57
|
+
try {
|
|
58
|
+
const dataFetchMap = getDataFetchMap();
|
|
59
|
+
if (!dataFetchMap) {
|
|
60
|
+
initDataFetchMap();
|
|
61
|
+
}
|
|
62
|
+
const fetchDataPromise = (_b = dataFetchMap[dataFetchKey]) == null ? void 0 : _b[1];
|
|
63
|
+
logger.debug(
|
|
64
|
+
"fetch data from server, fetchDataPromise: ",
|
|
65
|
+
fetchDataPromise
|
|
66
|
+
);
|
|
67
|
+
if (fetchDataPromise && ((_c = dataFetchMap[dataFetchKey]) == null ? void 0 : _c[2]) !== MF_DATA_FETCH_STATUS.ERROR) {
|
|
68
|
+
const targetPromise = fetchDataPromise[0];
|
|
69
|
+
const wrappedPromise = wrapSetTimeout(targetPromise, 2e4, dataFetchKey);
|
|
70
|
+
if (wrappedPromise) {
|
|
71
|
+
const res = await wrappedPromise;
|
|
72
|
+
logger.log("fetch data from server, fetchDataPromise res: ", res);
|
|
73
|
+
return ctx.json(res);
|
|
74
|
+
}
|
|
75
|
+
logger.error(
|
|
76
|
+
`Expected a Promise from fetchDataPromise[0] for dataFetchKey ${dataFetchKey}, but received:`,
|
|
77
|
+
targetPromise,
|
|
78
|
+
"Will try call new dataFetch again..."
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (remoteInfo) {
|
|
82
|
+
try {
|
|
83
|
+
const hostInstance2 = globalThis.__FEDERATION__.__INSTANCES__[0];
|
|
84
|
+
const remoteEntry = `${addProtocol(remoteInfo.ssrPublicPath) + remoteInfo.ssrRemoteEntry}`;
|
|
85
|
+
if (!hostInstance2) {
|
|
86
|
+
throw new Error("host instance not found!");
|
|
87
|
+
}
|
|
88
|
+
const remote = hostInstance2.options.remotes.find(
|
|
89
|
+
(remote2) => remote2.name === remoteInfo.name
|
|
90
|
+
);
|
|
91
|
+
logger.debug("find remote: ", JSON.stringify(remote));
|
|
92
|
+
if (!remote) {
|
|
93
|
+
hostInstance2.registerRemotes([
|
|
94
|
+
{
|
|
95
|
+
name: remoteInfo.name,
|
|
96
|
+
entry: remoteEntry,
|
|
97
|
+
entryGlobalName: remoteInfo.globalName
|
|
98
|
+
}
|
|
99
|
+
]);
|
|
100
|
+
} else if (!("entry" in remote) || !remote.entry.includes(MANIFEST_EXT)) {
|
|
101
|
+
const { hostGlobalSnapshot, remoteSnapshot } = hostInstance2.snapshotHandler.getGlobalRemoteInfo(remoteInfo);
|
|
102
|
+
logger.debug(
|
|
103
|
+
"find hostGlobalSnapshot: ",
|
|
104
|
+
JSON.stringify(hostGlobalSnapshot)
|
|
105
|
+
);
|
|
106
|
+
logger.debug("find remoteSnapshot: ", JSON.stringify(remoteSnapshot));
|
|
107
|
+
if (!hostGlobalSnapshot || !remoteSnapshot) {
|
|
108
|
+
if ("version" in remote) {
|
|
109
|
+
delete remote.version;
|
|
110
|
+
}
|
|
111
|
+
remote.entry = remoteEntry;
|
|
112
|
+
remote.entryGlobalName = remoteInfo.globalName;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {
|
|
116
|
+
ctx.status(500);
|
|
117
|
+
return ctx.text(
|
|
118
|
+
`failed to fetch ${remoteInfo.name} data, error:
|
|
119
|
+
${e}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const dataFetchItem = dataFetchMap[dataFetchKey];
|
|
124
|
+
logger.debug("fetch data from server, dataFetchItem: ", dataFetchItem);
|
|
125
|
+
if (dataFetchItem) {
|
|
126
|
+
const callFetchDataPromise = fetchData(dataFetchKey, {
|
|
127
|
+
...params,
|
|
128
|
+
isDowngrade: !remoteInfo,
|
|
129
|
+
_id: dataFetchKey
|
|
130
|
+
});
|
|
131
|
+
const wrappedPromise = wrapSetTimeout(
|
|
132
|
+
callFetchDataPromise,
|
|
133
|
+
2e4,
|
|
134
|
+
dataFetchKey
|
|
135
|
+
);
|
|
136
|
+
if (wrappedPromise) {
|
|
137
|
+
const res = await wrappedPromise;
|
|
138
|
+
logger.log("fetch data from server, dataFetchItem res: ", res);
|
|
139
|
+
return ctx.json(res);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const remoteId = dataFetchKey.split(SEPARATOR)[0];
|
|
143
|
+
const hostInstance = globalThis.__FEDERATION__.__INSTANCES__[0];
|
|
144
|
+
if (!hostInstance) {
|
|
145
|
+
throw new Error("host instance not found!");
|
|
146
|
+
}
|
|
147
|
+
const dataFetchFn = await loadDataFetchModule(hostInstance, remoteId);
|
|
148
|
+
const data = await dataFetchFn({
|
|
149
|
+
...params,
|
|
150
|
+
isDowngrade: !remoteInfo,
|
|
151
|
+
_id: dataFetchKey
|
|
152
|
+
});
|
|
153
|
+
logger.log("fetch data from server, loadDataFetchModule res: ", data);
|
|
154
|
+
return ctx.json(data);
|
|
155
|
+
} catch (e) {
|
|
156
|
+
logger.error("server plugin data fetch error: ", e);
|
|
157
|
+
ctx.status(500);
|
|
158
|
+
return ctx.text(`failed to fetch ${remoteInfo.name} data, error:
|
|
159
|
+
${e}`);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
export {
|
|
163
|
+
dataFetchServerMiddleware as default
|
|
164
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const lazyUtils = require("./utils-tM9yE73c.js");
|
|
4
|
+
const prefetch = require("./prefetch-A3QkU5oZ.js");
|
|
5
|
+
async function callDataFetch() {
|
|
6
|
+
const dataFetch = globalThis[lazyUtils.DATA_FETCH_FUNCTION];
|
|
7
|
+
if (dataFetch) {
|
|
8
|
+
await Promise.all(
|
|
9
|
+
dataFetch.map(async (options) => {
|
|
10
|
+
await prefetch.dataFetchFunction(options);
|
|
11
|
+
})
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.CacheSize = lazyUtils.CacheSize;
|
|
16
|
+
exports.CacheTime = lazyUtils.CacheTime;
|
|
17
|
+
exports.cache = lazyUtils.cache;
|
|
18
|
+
exports.clearStore = lazyUtils.clearStore;
|
|
19
|
+
exports.configureCache = lazyUtils.configureCache;
|
|
20
|
+
exports.generateKey = lazyUtils.generateKey;
|
|
21
|
+
exports.revalidateTag = lazyUtils.revalidateTag;
|
|
22
|
+
exports.injectDataFetch = prefetch.injectDataFetch;
|
|
23
|
+
exports.prefetch = prefetch.prefetch;
|
|
24
|
+
exports.callDataFetch = callDataFetch;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { getInstance } from '@module-federation/runtime';
|
|
2
|
+
|
|
3
|
+
export declare function cache<T>(fn: DataFetch<T>, options?: CacheOptions): DataFetch<T>;
|
|
4
|
+
|
|
5
|
+
declare interface CacheConfig {
|
|
6
|
+
maxSize?: number;
|
|
7
|
+
unstable_shouldDisable?: ({ request, }: {
|
|
8
|
+
request: Request;
|
|
9
|
+
}) => boolean | Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
declare interface CacheOptions {
|
|
13
|
+
tag?: string | string[];
|
|
14
|
+
maxAge?: number;
|
|
15
|
+
revalidate?: number;
|
|
16
|
+
getKey?: <Args extends any[]>(...args: Args) => string;
|
|
17
|
+
onCache?: (info: CacheStatsInfo) => boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare const CacheSize: {
|
|
21
|
+
readonly KB: 1024;
|
|
22
|
+
readonly MB: number;
|
|
23
|
+
readonly GB: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export declare interface CacheStatsInfo {
|
|
27
|
+
status: CacheStatus;
|
|
28
|
+
key: string | symbol;
|
|
29
|
+
params: DataFetchParams;
|
|
30
|
+
result: any;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export declare type CacheStatus = 'hit' | 'stale' | 'miss';
|
|
34
|
+
|
|
35
|
+
export declare const CacheTime: {
|
|
36
|
+
readonly SECOND: 1000;
|
|
37
|
+
readonly MINUTE: number;
|
|
38
|
+
readonly HOUR: number;
|
|
39
|
+
readonly DAY: number;
|
|
40
|
+
readonly WEEK: number;
|
|
41
|
+
readonly MONTH: number;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export declare function callDataFetch(): Promise<void>;
|
|
45
|
+
|
|
46
|
+
export declare function clearStore(): void;
|
|
47
|
+
|
|
48
|
+
export declare function configureCache(config: CacheConfig): void;
|
|
49
|
+
|
|
50
|
+
declare type DataFetch<T> = (params: DataFetchParams) => Promise<T>;
|
|
51
|
+
|
|
52
|
+
declare type DataFetchParams = {
|
|
53
|
+
isDowngrade: boolean;
|
|
54
|
+
_id?: string;
|
|
55
|
+
} & Record<string, unknown>;
|
|
56
|
+
|
|
57
|
+
export declare function generateKey(dataFetchOptions: DataFetchParams): string;
|
|
58
|
+
|
|
59
|
+
export declare function injectDataFetch(): void;
|
|
60
|
+
|
|
61
|
+
export declare function prefetch(options: PrefetchOptions): Promise<void>;
|
|
62
|
+
|
|
63
|
+
export declare type PrefetchOptions = {
|
|
64
|
+
id: string;
|
|
65
|
+
instance: ReturnType<typeof getInstance>;
|
|
66
|
+
dataFetchParams?: DataFetchParams;
|
|
67
|
+
preloadComponentResource?: boolean;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export declare function revalidateTag(tag: string): void;
|
|
71
|
+
|
|
72
|
+
export { }
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
declare module '@module-federation/runtime-core' {
|
|
76
|
+
interface ModuleFederation {
|
|
77
|
+
createLazyComponent<T, E extends keyof T>(options: Omit<CreateLazyComponentOptions<T, E>, 'instance'>): ReturnType<typeof createLazyComponent<T, E>>;
|
|
78
|
+
prefetch(options: Omit<PrefetchOptions, 'instance'>): ReturnType<typeof prefetch>;
|
|
79
|
+
collectSSRAssets(options: Omit<Parameters<typeof collectSSRAssets>[0], 'instance'>): ReturnType<typeof collectSSRAssets>;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { x as DATA_FETCH_FUNCTION } from "./utils-dUgb9Jkm.mjs";
|
|
2
|
+
import { C, a, b, d, c, g, r } from "./utils-dUgb9Jkm.mjs";
|
|
3
|
+
import { d as dataFetchFunction } from "./prefetch-zMJL79zx.mjs";
|
|
4
|
+
import { i, p } from "./prefetch-zMJL79zx.mjs";
|
|
5
|
+
async function callDataFetch() {
|
|
6
|
+
const dataFetch = globalThis[DATA_FETCH_FUNCTION];
|
|
7
|
+
if (dataFetch) {
|
|
8
|
+
await Promise.all(
|
|
9
|
+
dataFetch.map(async (options) => {
|
|
10
|
+
await dataFetchFunction(options);
|
|
11
|
+
})
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
C as CacheSize,
|
|
17
|
+
a as CacheTime,
|
|
18
|
+
b as cache,
|
|
19
|
+
callDataFetch,
|
|
20
|
+
d as clearStore,
|
|
21
|
+
c as configureCache,
|
|
22
|
+
g as generateKey,
|
|
23
|
+
i as injectDataFetch,
|
|
24
|
+
p as prefetch,
|
|
25
|
+
r as revalidateTag
|
|
26
|
+
};
|