@module-federation/bridge-react 0.0.0-next-20250708121428 → 0.0.0-next-20250709032753
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 +4 -8
- package/__tests__/bridge.spec.tsx +7 -7
- package/dist/{bridge-base-UGCwcMnG.js → bridge-base-BBH982Tz.cjs} +1 -1
- package/dist/{bridge-base-BoshEggF.mjs → bridge-base-P6pEjY1q.js} +1 -1
- package/dist/index-Cv3p6r66.cjs +235 -0
- package/dist/index-D4yt7Udv.js +236 -0
- package/dist/index.cjs.js +9 -35
- package/dist/index.d.ts +0 -143
- package/dist/index.es.js +12 -38
- package/dist/plugin.d.ts +0 -9
- package/dist/router-v5.cjs.js +1 -1
- package/dist/router-v5.d.ts +0 -9
- package/dist/router-v5.es.js +1 -1
- package/dist/router-v6.cjs.js +1 -1
- package/dist/router-v6.d.ts +0 -9
- package/dist/router-v6.es.js +1 -1
- package/dist/router.cjs.js +1 -1
- package/dist/router.d.ts +0 -9
- package/dist/router.es.js +1 -1
- package/dist/v18.cjs.js +1 -1
- package/dist/v18.d.ts +0 -9
- package/dist/v18.es.js +1 -1
- package/dist/v19.cjs.js +1 -1
- package/dist/v19.d.ts +0 -9
- package/dist/v19.es.js +1 -1
- package/package.json +5 -46
- package/src/.eslintrc.js +9 -0
- package/src/index.ts +1 -32
- package/src/remote/component.tsx +3 -3
- package/src/remote/create.tsx +4 -17
- package/tsconfig.json +1 -1
- package/vite.config.ts +0 -13
- package/dist/data-fetch-server-middleware.cjs.js +0 -163
- package/dist/data-fetch-server-middleware.d.ts +0 -15
- package/dist/data-fetch-server-middleware.es.js +0 -164
- package/dist/data-fetch-utils.cjs.js +0 -24
- package/dist/data-fetch-utils.d.ts +0 -86
- package/dist/data-fetch-utils.es.js +0 -26
- package/dist/index-C0fDZB5b.js +0 -45
- package/dist/index-CqxytsLY.mjs +0 -46
- package/dist/index.esm-BCeUd-x9.mjs +0 -418
- package/dist/index.esm-j_1sIRzg.js +0 -417
- package/dist/lazy-load-component-plugin-BbqmMGKu.mjs +0 -492
- package/dist/lazy-load-component-plugin-DgYHamxE.js +0 -491
- package/dist/lazy-load-component-plugin.cjs.js +0 -6
- package/dist/lazy-load-component-plugin.d.ts +0 -16
- package/dist/lazy-load-component-plugin.es.js +0 -6
- package/dist/lazy-utils.cjs.js +0 -24
- package/dist/lazy-utils.d.ts +0 -149
- package/dist/lazy-utils.es.js +0 -24
- package/dist/prefetch-BWabXlKU.js +0 -1332
- package/dist/prefetch-CXJhiNUD.mjs +0 -1333
- package/dist/utils-BTYYwZcb.mjs +0 -2016
- package/dist/utils-iEVlDmyk.js +0 -2015
- package/src/lazy/AwaitDataFetch.tsx +0 -215
- package/src/lazy/constant.ts +0 -30
- package/src/lazy/createLazyComponent.tsx +0 -418
- package/src/lazy/data-fetch/cache.ts +0 -296
- package/src/lazy/data-fetch/call-data-fetch.ts +0 -13
- package/src/lazy/data-fetch/data-fetch-server-middleware.ts +0 -196
- package/src/lazy/data-fetch/index.ts +0 -16
- package/src/lazy/data-fetch/inject-data-fetch.ts +0 -109
- package/src/lazy/data-fetch/prefetch.ts +0 -106
- package/src/lazy/data-fetch/runtime-plugin.ts +0 -115
- package/src/lazy/index.ts +0 -35
- package/src/lazy/logger.ts +0 -6
- package/src/lazy/types.ts +0 -75
- package/src/lazy/utils.ts +0 -372
- package/src/lazy/wrapNoSSR.tsx +0 -10
- package/src/plugins/lazy-load-component-plugin.ts +0 -62
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
import { LRUCache } from 'lru-cache';
|
|
2
|
-
import { getDataFetchCache } from '../utils';
|
|
3
|
-
|
|
4
|
-
import type {
|
|
5
|
-
CacheConfig,
|
|
6
|
-
CacheItem,
|
|
7
|
-
DataFetch,
|
|
8
|
-
DataFetchParams,
|
|
9
|
-
} from '../types';
|
|
10
|
-
|
|
11
|
-
export const CacheSize = {
|
|
12
|
-
KB: 1024,
|
|
13
|
-
MB: 1024 * 1024,
|
|
14
|
-
GB: 1024 * 1024 * 1024,
|
|
15
|
-
} as const;
|
|
16
|
-
|
|
17
|
-
export const CacheTime = {
|
|
18
|
-
SECOND: 1000,
|
|
19
|
-
MINUTE: 60 * 1000,
|
|
20
|
-
HOUR: 60 * 60 * 1000,
|
|
21
|
-
DAY: 24 * 60 * 60 * 1000,
|
|
22
|
-
WEEK: 7 * 24 * 60 * 60 * 1000,
|
|
23
|
-
MONTH: 30 * 24 * 60 * 60 * 1000,
|
|
24
|
-
} as const;
|
|
25
|
-
|
|
26
|
-
export type CacheStatus = 'hit' | 'stale' | 'miss';
|
|
27
|
-
|
|
28
|
-
export interface CacheStatsInfo {
|
|
29
|
-
status: CacheStatus;
|
|
30
|
-
key: string | symbol;
|
|
31
|
-
params: DataFetchParams;
|
|
32
|
-
result: any;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface CacheOptions {
|
|
36
|
-
tag?: string | string[];
|
|
37
|
-
maxAge?: number;
|
|
38
|
-
revalidate?: number;
|
|
39
|
-
getKey?: <Args extends any[]>(...args: Args) => string;
|
|
40
|
-
customKey?: <Args extends any[]>(options: {
|
|
41
|
-
params: Args;
|
|
42
|
-
fn: (...args: Args) => any;
|
|
43
|
-
generatedKey: string;
|
|
44
|
-
}) => string | symbol;
|
|
45
|
-
onCache?: (info: CacheStatsInfo) => boolean;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getTagKeyMap() {
|
|
49
|
-
const dataFetchCache = getDataFetchCache();
|
|
50
|
-
if (!dataFetchCache || !dataFetchCache.tagKeyMap) {
|
|
51
|
-
const tagKeyMap = new Map<string, Set<string>>();
|
|
52
|
-
globalThis.__MF_DATA_FETCH_CACHE__ ||= {};
|
|
53
|
-
globalThis.__MF_DATA_FETCH_CACHE__.tagKeyMap = tagKeyMap;
|
|
54
|
-
return tagKeyMap;
|
|
55
|
-
}
|
|
56
|
-
return dataFetchCache.tagKeyMap;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function addTagKeyRelation(tag: string, key: string) {
|
|
60
|
-
const tagKeyMap = getTagKeyMap();
|
|
61
|
-
let keys = tagKeyMap.get(tag);
|
|
62
|
-
if (!keys) {
|
|
63
|
-
keys = new Set();
|
|
64
|
-
tagKeyMap.set(tag, keys);
|
|
65
|
-
}
|
|
66
|
-
keys.add(key);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function getCacheConfig() {
|
|
70
|
-
const dataFetchCache = getDataFetchCache();
|
|
71
|
-
if (!dataFetchCache || !dataFetchCache.cacheConfig) {
|
|
72
|
-
const cacheConfig: CacheConfig = {
|
|
73
|
-
maxSize: CacheSize.GB,
|
|
74
|
-
};
|
|
75
|
-
globalThis.__MF_DATA_FETCH_CACHE__ ||= {};
|
|
76
|
-
globalThis.__MF_DATA_FETCH_CACHE__.cacheConfig = cacheConfig;
|
|
77
|
-
return cacheConfig;
|
|
78
|
-
}
|
|
79
|
-
return dataFetchCache.cacheConfig;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function configureCache(config: CacheConfig): void {
|
|
83
|
-
const cacheConfig = getCacheConfig();
|
|
84
|
-
Object.assign(cacheConfig, config);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function getLRUCache() {
|
|
88
|
-
const dataFetchCache = getDataFetchCache();
|
|
89
|
-
const cacheConfig = getCacheConfig();
|
|
90
|
-
|
|
91
|
-
if (!dataFetchCache || !dataFetchCache.cacheStore) {
|
|
92
|
-
const cacheStore = new LRUCache<string, Map<string, CacheItem<any>>>({
|
|
93
|
-
maxSize: cacheConfig.maxSize ?? CacheSize.GB,
|
|
94
|
-
sizeCalculation: (value: Map<string, CacheItem<any>>): number => {
|
|
95
|
-
if (!value.size) {
|
|
96
|
-
return 1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let size = 0;
|
|
100
|
-
for (const [k, item] of value.entries()) {
|
|
101
|
-
size += k.length * 2;
|
|
102
|
-
size += estimateObjectSize(item.data);
|
|
103
|
-
size += 8;
|
|
104
|
-
}
|
|
105
|
-
return size;
|
|
106
|
-
},
|
|
107
|
-
updateAgeOnGet: true,
|
|
108
|
-
updateAgeOnHas: true,
|
|
109
|
-
});
|
|
110
|
-
globalThis.__MF_DATA_FETCH_CACHE__ ||= {};
|
|
111
|
-
globalThis.__MF_DATA_FETCH_CACHE__.cacheStore = cacheStore;
|
|
112
|
-
return cacheStore;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return dataFetchCache.cacheStore;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function estimateObjectSize(data: unknown): number {
|
|
119
|
-
const type = typeof data;
|
|
120
|
-
|
|
121
|
-
if (type === 'number') return 8;
|
|
122
|
-
if (type === 'boolean') return 4;
|
|
123
|
-
if (type === 'string') return Math.max((data as string).length * 2, 1);
|
|
124
|
-
if (data === null || data === undefined) return 1;
|
|
125
|
-
|
|
126
|
-
if (ArrayBuffer.isView(data)) {
|
|
127
|
-
return Math.max(data.byteLength, 1);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (Array.isArray(data)) {
|
|
131
|
-
return Math.max(
|
|
132
|
-
data.reduce((acc, item) => acc + estimateObjectSize(item), 0),
|
|
133
|
-
1,
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (data instanceof Map || data instanceof Set) {
|
|
138
|
-
return 1024;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (data instanceof Date) {
|
|
142
|
-
return 8;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (type === 'object') {
|
|
146
|
-
return Math.max(
|
|
147
|
-
Object.entries(data).reduce(
|
|
148
|
-
(acc, [key, value]) => acc + key.length * 2 + estimateObjectSize(value),
|
|
149
|
-
0,
|
|
150
|
-
),
|
|
151
|
-
1,
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return 1;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export function generateKey(dataFetchOptions: DataFetchParams): string {
|
|
159
|
-
return JSON.stringify(dataFetchOptions, (_, value) => {
|
|
160
|
-
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
161
|
-
return Object.keys(value)
|
|
162
|
-
.sort()
|
|
163
|
-
.reduce((result: Record<string, unknown>, key) => {
|
|
164
|
-
result[key] = value[key];
|
|
165
|
-
return result;
|
|
166
|
-
}, {});
|
|
167
|
-
}
|
|
168
|
-
return value;
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export function cache<T>(
|
|
173
|
-
fn: DataFetch<T>,
|
|
174
|
-
options?: CacheOptions,
|
|
175
|
-
): DataFetch<T> {
|
|
176
|
-
const {
|
|
177
|
-
tag = 'default',
|
|
178
|
-
maxAge = CacheTime.MINUTE * 5,
|
|
179
|
-
revalidate = 0,
|
|
180
|
-
onCache,
|
|
181
|
-
getKey,
|
|
182
|
-
} = options || {};
|
|
183
|
-
|
|
184
|
-
const tags = Array.isArray(tag) ? tag : [tag];
|
|
185
|
-
|
|
186
|
-
return async (dataFetchOptions) => {
|
|
187
|
-
// if downgrade, skip cache
|
|
188
|
-
if (dataFetchOptions.isDowngrade || !dataFetchOptions._id) {
|
|
189
|
-
return fn(dataFetchOptions);
|
|
190
|
-
}
|
|
191
|
-
const store = getLRUCache();
|
|
192
|
-
|
|
193
|
-
const now = Date.now();
|
|
194
|
-
const storeKey = dataFetchOptions._id;
|
|
195
|
-
const cacheKey = getKey
|
|
196
|
-
? getKey(dataFetchOptions)
|
|
197
|
-
: generateKey(dataFetchOptions);
|
|
198
|
-
|
|
199
|
-
tags.forEach((t) => addTagKeyRelation(t, cacheKey));
|
|
200
|
-
|
|
201
|
-
let cacheStore = store.get(cacheKey);
|
|
202
|
-
if (!cacheStore) {
|
|
203
|
-
cacheStore = new Map();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const cached = cacheStore.get(storeKey);
|
|
207
|
-
if (cached) {
|
|
208
|
-
const age = now - cached.timestamp;
|
|
209
|
-
|
|
210
|
-
if (age < maxAge) {
|
|
211
|
-
if (onCache) {
|
|
212
|
-
const useCache = onCache({
|
|
213
|
-
status: 'hit',
|
|
214
|
-
key: cacheKey,
|
|
215
|
-
params: dataFetchOptions,
|
|
216
|
-
result: cached.data,
|
|
217
|
-
});
|
|
218
|
-
if (!useCache) {
|
|
219
|
-
return fn(dataFetchOptions);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return cached.data;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (revalidate > 0 && age < maxAge + revalidate) {
|
|
226
|
-
if (onCache) {
|
|
227
|
-
onCache({
|
|
228
|
-
status: 'stale',
|
|
229
|
-
key: cacheKey,
|
|
230
|
-
params: dataFetchOptions,
|
|
231
|
-
result: cached.data,
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (!cached.isRevalidating) {
|
|
236
|
-
cached.isRevalidating = true;
|
|
237
|
-
Promise.resolve().then(async () => {
|
|
238
|
-
try {
|
|
239
|
-
const newData = await fn(dataFetchOptions);
|
|
240
|
-
cacheStore!.set(storeKey, {
|
|
241
|
-
data: newData,
|
|
242
|
-
timestamp: Date.now(),
|
|
243
|
-
isRevalidating: false,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
store.set(cacheKey, cacheStore!);
|
|
247
|
-
} catch (error) {
|
|
248
|
-
cached.isRevalidating = false;
|
|
249
|
-
console.error('Background revalidation failed:', error);
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
return cached.data;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const data = await fn(dataFetchOptions);
|
|
258
|
-
cacheStore.set(storeKey, {
|
|
259
|
-
data,
|
|
260
|
-
timestamp: now,
|
|
261
|
-
isRevalidating: false,
|
|
262
|
-
});
|
|
263
|
-
store.set(cacheKey, cacheStore);
|
|
264
|
-
|
|
265
|
-
if (onCache) {
|
|
266
|
-
onCache({
|
|
267
|
-
status: 'miss',
|
|
268
|
-
key: cacheKey,
|
|
269
|
-
params: dataFetchOptions,
|
|
270
|
-
result: data,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return data;
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export function revalidateTag(tag: string): void {
|
|
279
|
-
const tagKeyMap = getTagKeyMap();
|
|
280
|
-
const keys = tagKeyMap.get(tag);
|
|
281
|
-
const lruCache = getLRUCache();
|
|
282
|
-
if (keys) {
|
|
283
|
-
keys.forEach((key) => {
|
|
284
|
-
lruCache?.delete(key);
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export function clearStore(): void {
|
|
290
|
-
const lruCache = getLRUCache();
|
|
291
|
-
const tagKeyMap = getTagKeyMap();
|
|
292
|
-
|
|
293
|
-
lruCache?.clear();
|
|
294
|
-
delete globalThis.__MF_DATA_FETCH_CACHE__?.cacheStore;
|
|
295
|
-
tagKeyMap.clear();
|
|
296
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { DATA_FETCH_FUNCTION } from '../constant';
|
|
2
|
-
import { dataFetchFunction } from './inject-data-fetch';
|
|
3
|
-
|
|
4
|
-
export async function callDataFetch() {
|
|
5
|
-
const dataFetch = globalThis[DATA_FETCH_FUNCTION];
|
|
6
|
-
if (dataFetch) {
|
|
7
|
-
await Promise.all(
|
|
8
|
-
dataFetch.map(async (options) => {
|
|
9
|
-
await dataFetchFunction(options);
|
|
10
|
-
}),
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { DATA_FETCH_QUERY, MF_DATA_FETCH_STATUS } from '../constant';
|
|
2
|
-
import {
|
|
3
|
-
getDataFetchMap,
|
|
4
|
-
fetchData,
|
|
5
|
-
initDataFetchMap,
|
|
6
|
-
loadDataFetchModule,
|
|
7
|
-
} from '../utils';
|
|
8
|
-
import { SEPARATOR, MANIFEST_EXT } from '@module-federation/sdk';
|
|
9
|
-
import logger from '../logger';
|
|
10
|
-
|
|
11
|
-
import type { NoSSRRemoteInfo } from '../types';
|
|
12
|
-
import type { MiddlewareHandler } from 'hono';
|
|
13
|
-
|
|
14
|
-
function wrapSetTimeout(
|
|
15
|
-
targetPromise: Promise<unknown>,
|
|
16
|
-
delay = 20000,
|
|
17
|
-
id: string,
|
|
18
|
-
) {
|
|
19
|
-
if (targetPromise && typeof targetPromise.then === 'function') {
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
const timeoutId = setTimeout(() => {
|
|
22
|
-
logger.warn(`Data fetch for ID ${id} timed out after 20 seconds.`);
|
|
23
|
-
reject(new Error(`Data fetch for ID ${id} timed out after 20 seconds`));
|
|
24
|
-
}, delay);
|
|
25
|
-
|
|
26
|
-
targetPromise
|
|
27
|
-
.then((value: any) => {
|
|
28
|
-
clearTimeout(timeoutId);
|
|
29
|
-
resolve(value);
|
|
30
|
-
})
|
|
31
|
-
.catch((err: any) => {
|
|
32
|
-
clearTimeout(timeoutId);
|
|
33
|
-
reject(err);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function addProtocol(url: string) {
|
|
40
|
-
if (url.startsWith('//')) {
|
|
41
|
-
return 'https:' + url;
|
|
42
|
-
}
|
|
43
|
-
return url;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const getDecodeQuery = (url: URL, name: string) => {
|
|
47
|
-
const res = url.searchParams.get(name);
|
|
48
|
-
if (!res) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
return decodeURIComponent(res);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const dataFetchServerMiddleware: MiddlewareHandler = async (ctx, next) => {
|
|
55
|
-
let url: URL;
|
|
56
|
-
let dataFetchKey: string | null;
|
|
57
|
-
let params: Record<string, unknown>;
|
|
58
|
-
let remoteInfo: NoSSRRemoteInfo;
|
|
59
|
-
try {
|
|
60
|
-
url = new URL(ctx.req.url);
|
|
61
|
-
dataFetchKey = getDecodeQuery(url, DATA_FETCH_QUERY);
|
|
62
|
-
params = JSON.parse(getDecodeQuery(url, 'params') || '{}');
|
|
63
|
-
const remoteInfoQuery = getDecodeQuery(url, 'remoteInfo');
|
|
64
|
-
remoteInfo = remoteInfoQuery ? JSON.parse(remoteInfoQuery) : null;
|
|
65
|
-
} catch (e) {
|
|
66
|
-
logger.error('fetch data from server, error: ', e);
|
|
67
|
-
return next();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (!dataFetchKey) {
|
|
71
|
-
return next();
|
|
72
|
-
}
|
|
73
|
-
logger.log('fetch data from server, dataFetchKey: ', dataFetchKey);
|
|
74
|
-
logger.debug(
|
|
75
|
-
'fetch data from server, moduleInfo: ',
|
|
76
|
-
globalThis.__FEDERATION__?.moduleInfo,
|
|
77
|
-
);
|
|
78
|
-
try {
|
|
79
|
-
const dataFetchMap = getDataFetchMap();
|
|
80
|
-
if (!dataFetchMap) {
|
|
81
|
-
initDataFetchMap();
|
|
82
|
-
}
|
|
83
|
-
const fetchDataPromise = dataFetchMap[dataFetchKey]?.[1];
|
|
84
|
-
logger.debug(
|
|
85
|
-
'fetch data from server, fetchDataPromise: ',
|
|
86
|
-
fetchDataPromise,
|
|
87
|
-
);
|
|
88
|
-
if (
|
|
89
|
-
fetchDataPromise &&
|
|
90
|
-
dataFetchMap[dataFetchKey]?.[2] !== MF_DATA_FETCH_STATUS.ERROR
|
|
91
|
-
) {
|
|
92
|
-
const targetPromise = fetchDataPromise[0];
|
|
93
|
-
// Ensure targetPromise is thenable
|
|
94
|
-
const wrappedPromise = wrapSetTimeout(targetPromise, 20000, dataFetchKey);
|
|
95
|
-
if (wrappedPromise) {
|
|
96
|
-
const res = await wrappedPromise;
|
|
97
|
-
logger.log('fetch data from server, fetchDataPromise res: ', res);
|
|
98
|
-
return ctx.json(res);
|
|
99
|
-
}
|
|
100
|
-
logger.error(
|
|
101
|
-
`Expected a Promise from fetchDataPromise[0] for dataFetchKey ${dataFetchKey}, but received:`,
|
|
102
|
-
targetPromise,
|
|
103
|
-
'Will try call new dataFetch again...',
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (remoteInfo) {
|
|
108
|
-
try {
|
|
109
|
-
const hostInstance = globalThis.__FEDERATION__.__INSTANCES__[0];
|
|
110
|
-
const remoteEntry = `${addProtocol(remoteInfo.ssrPublicPath) + remoteInfo.ssrRemoteEntry}`;
|
|
111
|
-
if (!hostInstance) {
|
|
112
|
-
throw new Error('host instance not found!');
|
|
113
|
-
}
|
|
114
|
-
const remote = hostInstance.options.remotes.find(
|
|
115
|
-
(remote) => remote.name === remoteInfo.name,
|
|
116
|
-
);
|
|
117
|
-
logger.debug('find remote: ', JSON.stringify(remote));
|
|
118
|
-
if (!remote) {
|
|
119
|
-
hostInstance.registerRemotes([
|
|
120
|
-
{
|
|
121
|
-
name: remoteInfo.name,
|
|
122
|
-
entry: remoteEntry,
|
|
123
|
-
entryGlobalName: remoteInfo.globalName,
|
|
124
|
-
},
|
|
125
|
-
]);
|
|
126
|
-
} else if (
|
|
127
|
-
!('entry' in remote) ||
|
|
128
|
-
!remote.entry.includes(MANIFEST_EXT)
|
|
129
|
-
) {
|
|
130
|
-
const { hostGlobalSnapshot, remoteSnapshot } =
|
|
131
|
-
hostInstance.snapshotHandler.getGlobalRemoteInfo(remoteInfo);
|
|
132
|
-
logger.debug(
|
|
133
|
-
'find hostGlobalSnapshot: ',
|
|
134
|
-
JSON.stringify(hostGlobalSnapshot),
|
|
135
|
-
);
|
|
136
|
-
logger.debug('find remoteSnapshot: ', JSON.stringify(remoteSnapshot));
|
|
137
|
-
|
|
138
|
-
if (!hostGlobalSnapshot || !remoteSnapshot) {
|
|
139
|
-
if ('version' in remote) {
|
|
140
|
-
// @ts-ignore
|
|
141
|
-
delete remote.version;
|
|
142
|
-
}
|
|
143
|
-
// @ts-ignore
|
|
144
|
-
remote.entry = remoteEntry;
|
|
145
|
-
remote.entryGlobalName = remoteInfo.globalName;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
} catch (e) {
|
|
149
|
-
ctx.status(500);
|
|
150
|
-
return ctx.text(
|
|
151
|
-
`failed to fetch ${remoteInfo.name} data, error:\n ${e}`,
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const dataFetchItem = dataFetchMap[dataFetchKey];
|
|
157
|
-
logger.debug('fetch data from server, dataFetchItem: ', dataFetchItem);
|
|
158
|
-
if (dataFetchItem) {
|
|
159
|
-
const callFetchDataPromise = fetchData(dataFetchKey, {
|
|
160
|
-
...params,
|
|
161
|
-
isDowngrade: !remoteInfo,
|
|
162
|
-
_id: dataFetchKey,
|
|
163
|
-
});
|
|
164
|
-
const wrappedPromise = wrapSetTimeout(
|
|
165
|
-
callFetchDataPromise,
|
|
166
|
-
20000,
|
|
167
|
-
dataFetchKey,
|
|
168
|
-
);
|
|
169
|
-
if (wrappedPromise) {
|
|
170
|
-
const res = await wrappedPromise;
|
|
171
|
-
logger.log('fetch data from server, dataFetchItem res: ', res);
|
|
172
|
-
return ctx.json(res);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const remoteId = dataFetchKey.split(SEPARATOR)[0];
|
|
177
|
-
const hostInstance = globalThis.__FEDERATION__.__INSTANCES__[0];
|
|
178
|
-
if (!hostInstance) {
|
|
179
|
-
throw new Error('host instance not found!');
|
|
180
|
-
}
|
|
181
|
-
const dataFetchFn = await loadDataFetchModule(hostInstance, remoteId);
|
|
182
|
-
const data = await dataFetchFn({
|
|
183
|
-
...params,
|
|
184
|
-
isDowngrade: !remoteInfo,
|
|
185
|
-
_id: dataFetchKey,
|
|
186
|
-
});
|
|
187
|
-
logger.log('fetch data from server, loadDataFetchModule res: ', data);
|
|
188
|
-
return ctx.json(data);
|
|
189
|
-
} catch (e) {
|
|
190
|
-
logger.error('server plugin data fetch error: ', e);
|
|
191
|
-
ctx.status(500);
|
|
192
|
-
return ctx.text(`failed to fetch ${remoteInfo.name} data, error:\n ${e}`);
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
export default dataFetchServerMiddleware;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export { callDataFetch } from './call-data-fetch';
|
|
2
|
-
export { injectDataFetch } from './inject-data-fetch';
|
|
3
|
-
export {
|
|
4
|
-
CacheSize,
|
|
5
|
-
CacheTime,
|
|
6
|
-
configureCache,
|
|
7
|
-
generateKey,
|
|
8
|
-
cache,
|
|
9
|
-
revalidateTag,
|
|
10
|
-
clearStore,
|
|
11
|
-
} from './cache';
|
|
12
|
-
|
|
13
|
-
export type { CacheStatus, CacheStatsInfo } from './cache';
|
|
14
|
-
|
|
15
|
-
export type { PrefetchOptions } from './prefetch';
|
|
16
|
-
export { prefetch } from './prefetch';
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DATA_FETCH_FUNCTION,
|
|
3
|
-
DOWNGRADE_KEY,
|
|
4
|
-
FS_HREF,
|
|
5
|
-
MF_DATA_FETCH_STATUS,
|
|
6
|
-
MF_DATA_FETCH_TYPE,
|
|
7
|
-
} from '../constant';
|
|
8
|
-
import logger from '../logger';
|
|
9
|
-
import {
|
|
10
|
-
dataFetchFunctionOptions,
|
|
11
|
-
MF_DATA_FETCH_MAP_VALUE_PROMISE_SET,
|
|
12
|
-
} from '../types';
|
|
13
|
-
import {
|
|
14
|
-
callAllDowngrade,
|
|
15
|
-
callDowngrade,
|
|
16
|
-
getDataFetchItem,
|
|
17
|
-
getDataFetchMap,
|
|
18
|
-
getDowngradeTag,
|
|
19
|
-
initDataFetchMap,
|
|
20
|
-
} from '../utils';
|
|
21
|
-
|
|
22
|
-
const dataFetchFunction = async function (options: dataFetchFunctionOptions) {
|
|
23
|
-
const [id, data, downgrade] = options;
|
|
24
|
-
logger.debug('==========call data fetch function!');
|
|
25
|
-
if (data) {
|
|
26
|
-
if (!id) {
|
|
27
|
-
throw new Error('id is required!');
|
|
28
|
-
}
|
|
29
|
-
if (!getDataFetchMap()) {
|
|
30
|
-
initDataFetchMap();
|
|
31
|
-
}
|
|
32
|
-
const dataFetchItem = getDataFetchItem(id);
|
|
33
|
-
if (dataFetchItem) {
|
|
34
|
-
dataFetchItem[1]?.[1]?.(data);
|
|
35
|
-
dataFetchItem[2] = MF_DATA_FETCH_STATUS.LOADED;
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (!dataFetchItem) {
|
|
39
|
-
const dataFetchMap = getDataFetchMap();
|
|
40
|
-
let res: MF_DATA_FETCH_MAP_VALUE_PROMISE_SET[1];
|
|
41
|
-
let rej: MF_DATA_FETCH_MAP_VALUE_PROMISE_SET[2];
|
|
42
|
-
const p = new Promise((resolve, reject) => {
|
|
43
|
-
res = resolve;
|
|
44
|
-
rej = reject;
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
dataFetchMap[id] = [
|
|
48
|
-
[
|
|
49
|
-
async () => async () => {
|
|
50
|
-
return '';
|
|
51
|
-
},
|
|
52
|
-
MF_DATA_FETCH_TYPE.FETCH_SERVER,
|
|
53
|
-
],
|
|
54
|
-
[p, res, rej],
|
|
55
|
-
MF_DATA_FETCH_STATUS.LOADED,
|
|
56
|
-
];
|
|
57
|
-
res && res(data);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (downgrade) {
|
|
63
|
-
const mfDowngrade = getDowngradeTag();
|
|
64
|
-
if (!mfDowngrade) {
|
|
65
|
-
globalThis[DOWNGRADE_KEY] = id ? [id] : true;
|
|
66
|
-
} else if (Array.isArray(mfDowngrade) && id && !mfDowngrade.includes(id)) {
|
|
67
|
-
mfDowngrade.push(id);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const mfDowngrade = getDowngradeTag();
|
|
72
|
-
|
|
73
|
-
if (typeof mfDowngrade === 'boolean') {
|
|
74
|
-
return callAllDowngrade();
|
|
75
|
-
}
|
|
76
|
-
if (Array.isArray(mfDowngrade)) {
|
|
77
|
-
if (!id) {
|
|
78
|
-
globalThis[DOWNGRADE_KEY] = true;
|
|
79
|
-
return callAllDowngrade();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (!mfDowngrade.includes(id)) {
|
|
83
|
-
mfDowngrade.push(id);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return callDowngrade(id);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export function injectDataFetch() {
|
|
91
|
-
globalThis[DATA_FETCH_FUNCTION] ||= [];
|
|
92
|
-
const dataFetch = globalThis[DATA_FETCH_FUNCTION];
|
|
93
|
-
|
|
94
|
-
//@ts-ignore
|
|
95
|
-
if (dataFetch.push === dataFetchFunction) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (typeof window === 'undefined') {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
globalThis[FS_HREF] = window.location.href;
|
|
104
|
-
|
|
105
|
-
//@ts-ignore
|
|
106
|
-
dataFetch.push = dataFetchFunction;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export { dataFetchFunction };
|