@tramvai/module-child-app 5.50.0 → 5.53.74
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/lib/browser/loader.browser.js +18 -5
- package/lib/browser/loader.d.ts +10 -2
- package/lib/browser/preload.browser.js +85 -29
- package/lib/browser/preload.d.ts +14 -2
- package/lib/browser/providers.browser.js +17 -2
- package/lib/browser/render.browser.js +15 -1
- package/lib/browser/render.d.ts +10 -2
- package/lib/browser/runCommand.browser.js +1 -1
- package/lib/browser/runCommand.d.ts +1 -1
- package/lib/browser/timing.browser.js +100 -0
- package/lib/browser/timing.d.ts +4 -0
- package/lib/browser.js +2 -1
- package/lib/contracts/contractManager.base.browser.js +4 -0
- package/lib/contracts/contractManager.base.es.js +4 -0
- package/lib/contracts/contractManager.base.js +4 -0
- package/lib/contracts/contractManager.server.es.js +1 -0
- package/lib/contracts/contractManager.server.js +1 -0
- package/lib/server/loader.d.ts +15 -6
- package/lib/server/loader.es.js +63 -13
- package/lib/server/loader.js +63 -13
- package/lib/server/module-federation/best-loaded-shared-modules.d.ts +15 -0
- package/lib/server/module-federation/best-loaded-shared-modules.es.js +26 -0
- package/lib/server/module-federation/best-loaded-shared-modules.js +30 -0
- package/lib/server/module-federation/best-shared-modules.d.ts +15 -0
- package/lib/server/module-federation/utils.d.ts +18 -0
- package/lib/server/module-federation/utils.es.js +38 -0
- package/lib/server/module-federation/utils.js +43 -0
- package/lib/server/preload.d.ts +13 -2
- package/lib/server/preload.es.js +58 -19
- package/lib/server/preload.js +58 -19
- package/lib/server/providers.es.js +16 -3
- package/lib/server/providers.js +13 -0
- package/lib/server/render-slots.es.js +62 -50
- package/lib/server/render-slots.js +62 -50
- package/lib/server/render.d.ts +9 -2
- package/lib/server/render.es.js +13 -2
- package/lib/server/render.js +13 -2
- package/lib/server/stateManager.es.js +3 -1
- package/lib/server/stateManager.js +3 -1
- package/lib/shared/command.browser.js +4 -0
- package/lib/shared/command.es.js +4 -0
- package/lib/shared/command.js +4 -0
- package/lib/shared/di.browser.js +5 -1
- package/lib/shared/di.es.js +5 -1
- package/lib/shared/di.js +5 -1
- package/lib/shared/pageService.browser.js +8 -3
- package/lib/shared/pageService.es.js +8 -3
- package/lib/shared/pageService.js +8 -3
- package/lib/shared/providers.browser.js +8 -3
- package/lib/shared/providers.es.js +8 -3
- package/lib/shared/providers.js +6 -1
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.browser.js +56 -0
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.d.ts +45 -0
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.es.js +56 -0
- package/lib/shared/react/ChildAppErrorBoundary/ChildAppErrorBoundary.js +60 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.browser.js +21 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.d.ts +5 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.es.js +21 -0
- package/lib/shared/react/ChildAppErrorBoundary/FallbackError.js +25 -0
- package/lib/shared/react/ChildAppFallbackWrapper.browser.js +14 -0
- package/lib/shared/react/ChildAppFallbackWrapper.d.ts +10 -0
- package/lib/shared/react/ChildAppFallbackWrapper.es.js +14 -0
- package/lib/shared/react/ChildAppFallbackWrapper.js +18 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.browser.js +22 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.d.ts +8 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.es.js +22 -0
- package/lib/shared/react/childAppErrorBoundaryWrapper.js +26 -0
- package/lib/shared/react/component.browser.js +31 -6
- package/lib/shared/react/component.es.js +31 -6
- package/lib/shared/react/component.js +29 -4
- package/lib/shared/resolutionConfigManager.browser.js +35 -15
- package/lib/shared/resolutionConfigManager.d.ts +8 -2
- package/lib/shared/resolutionConfigManager.es.js +35 -15
- package/lib/shared/resolutionConfigManager.js +35 -15
- package/lib/shared/singletonDi.browser.js +18 -2
- package/lib/shared/singletonDi.d.ts +1 -0
- package/lib/shared/singletonDi.es.js +18 -2
- package/lib/shared/singletonDi.js +18 -2
- package/lib/shared/store.browser.js +15 -2
- package/lib/shared/store.d.ts +6 -0
- package/lib/shared/store.es.js +15 -2
- package/lib/shared/store.js +15 -1
- package/lib/shared/webpack/moduleFederation.browser.js +42 -0
- package/lib/shared/webpack/moduleFederation.d.ts +27 -18
- package/lib/shared/webpack/moduleFederation.es.js +42 -0
- package/lib/shared/webpack/moduleFederation.js +42 -0
- package/package.json +16 -16
- package/lib/shared/react/childAppErrorBoundary.browser.js +0 -14
- package/lib/shared/react/childAppErrorBoundary.d.ts +0 -8
- package/lib/shared/react/childAppErrorBoundary.es.js +0 -14
- package/lib/shared/react/childAppErrorBoundary.js +0 -18
package/lib/server/loader.es.js
CHANGED
|
@@ -4,25 +4,75 @@ import { Loader } from '../shared/loader.es.js';
|
|
|
4
4
|
import { initModuleFederation, getModuleFederation } from '../shared/webpack/moduleFederation.es.js';
|
|
5
5
|
|
|
6
6
|
class ServerLoader extends Loader {
|
|
7
|
-
|
|
7
|
+
loader;
|
|
8
|
+
initializedMap = new WeakMap();
|
|
9
|
+
log;
|
|
10
|
+
hookFactory;
|
|
11
|
+
loadModuleHook;
|
|
12
|
+
constructor({ logger, createCache, envManager, cacheOptions, asyncLocalStorage, hookFactory, plugins, }) {
|
|
8
13
|
super();
|
|
9
|
-
this.
|
|
14
|
+
this.hookFactory = hookFactory;
|
|
10
15
|
const cache = createCache('memory', {
|
|
11
16
|
name: 'child-app-loader',
|
|
12
17
|
ttl: 1000 * 60 * 60 * 24 * 5,
|
|
13
|
-
|
|
18
|
+
// When Child App script is evicted from server loader cache, we get a small memory leak,
|
|
19
|
+
// because providers in singleton child DI, page components / actions, will store a reference to removed script,
|
|
20
|
+
// and server loader cache will contain a new instance of the same script.
|
|
21
|
+
//
|
|
22
|
+
// So, it is better to have bigger cache size to prevent evicting from cache,
|
|
23
|
+
// also for one Child App we need to save 3 elements - server JS, stats JSON and loadable stats JSON.
|
|
24
|
+
//
|
|
25
|
+
// TODO: cache cleanup for previous versions of Child Apps
|
|
26
|
+
max: 100,
|
|
27
|
+
...cacheOptions,
|
|
14
28
|
});
|
|
15
|
-
|
|
29
|
+
let internalLoadCache = cache;
|
|
30
|
+
// Cache is not compatible with HMR (Hot Module Replacement) because after HMR and page reload,
|
|
31
|
+
// we get the page from the cache. To solve this, we use Async Local Storage to ensure the
|
|
32
|
+
// cache is only valid within the context of a single request.
|
|
33
|
+
if (process.env.NODE_ENV === 'development' && !!asyncLocalStorage) {
|
|
34
|
+
internalLoadCache = {
|
|
35
|
+
get(key) {
|
|
36
|
+
if (key?.startsWith('__DEBUG__')) {
|
|
37
|
+
const store = asyncLocalStorage.getStore();
|
|
38
|
+
if (store) {
|
|
39
|
+
return store[key];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return cache.get(key);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
set(key, module) {
|
|
47
|
+
if (key?.startsWith('__DEBUG__')) {
|
|
48
|
+
const store = asyncLocalStorage.getStore();
|
|
49
|
+
if (store) {
|
|
50
|
+
store[key] = module;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
cache.set(key, module);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
16
59
|
this.log = logger('child-app:loader');
|
|
17
60
|
this.loader = new ServerLoader$1({
|
|
18
|
-
cache,
|
|
61
|
+
cache: internalLoadCache,
|
|
19
62
|
log: this.log,
|
|
20
63
|
requestOptions: {
|
|
21
64
|
circuitBreakerEnabled: isNil(envManager.get('HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED')),
|
|
22
65
|
},
|
|
23
66
|
});
|
|
67
|
+
this.loadModuleHook = this.hookFactory.createAsync('childAppLoadModule');
|
|
68
|
+
this.loadModuleHook.tapPromise('childAppLoadModule', async (_, payload) => {
|
|
69
|
+
return this.loadModule(payload);
|
|
70
|
+
});
|
|
71
|
+
plugins?.forEach((plugin) => {
|
|
72
|
+
plugin.apply({ loadModule: this.loadModuleHook });
|
|
73
|
+
});
|
|
24
74
|
}
|
|
25
|
-
async
|
|
75
|
+
async loadModule({ config }) {
|
|
26
76
|
const promises = [
|
|
27
77
|
this.loader.resolveByUrl(config.server.entry, {
|
|
28
78
|
codePrefix: `var ASSETS_PREFIX="${config.client.baseUrl}";`,
|
|
@@ -53,15 +103,12 @@ class ServerLoader extends Loader {
|
|
|
53
103
|
}
|
|
54
104
|
await Promise.all(promises);
|
|
55
105
|
await this.init(config);
|
|
56
|
-
if (config.tag === 'debug') {
|
|
57
|
-
setTimeout(() => {
|
|
58
|
-
this.internalLoadCache.set(config.server.entry, null);
|
|
59
|
-
this.internalLoadCache.set(config.client.stats, null);
|
|
60
|
-
this.internalLoadCache.set(config.client.statsLoadable, null);
|
|
61
|
-
}, 10000);
|
|
62
|
-
}
|
|
63
106
|
return this.get(config);
|
|
64
107
|
}
|
|
108
|
+
async load(config) {
|
|
109
|
+
const childApp = await this.loadModuleHook.callPromise({ config });
|
|
110
|
+
return childApp;
|
|
111
|
+
}
|
|
65
112
|
async init(config) {
|
|
66
113
|
const container = this.loader.getByUrl(config.server.entry);
|
|
67
114
|
if (!container) {
|
|
@@ -87,6 +134,9 @@ class ServerLoader extends Loader {
|
|
|
87
134
|
}
|
|
88
135
|
get(config) {
|
|
89
136
|
const container = this.loader.getByUrl(config.server.entry);
|
|
137
|
+
if (!container) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
90
140
|
const entry = container && this.initializedMap.get(container);
|
|
91
141
|
return entry && this.resolve(entry);
|
|
92
142
|
}
|
package/lib/server/loader.js
CHANGED
|
@@ -12,25 +12,75 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
12
12
|
var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
|
|
13
13
|
|
|
14
14
|
class ServerLoader extends loader.Loader {
|
|
15
|
-
|
|
15
|
+
loader;
|
|
16
|
+
initializedMap = new WeakMap();
|
|
17
|
+
log;
|
|
18
|
+
hookFactory;
|
|
19
|
+
loadModuleHook;
|
|
20
|
+
constructor({ logger, createCache, envManager, cacheOptions, asyncLocalStorage, hookFactory, plugins, }) {
|
|
16
21
|
super();
|
|
17
|
-
this.
|
|
22
|
+
this.hookFactory = hookFactory;
|
|
18
23
|
const cache = createCache('memory', {
|
|
19
24
|
name: 'child-app-loader',
|
|
20
25
|
ttl: 1000 * 60 * 60 * 24 * 5,
|
|
21
|
-
|
|
26
|
+
// When Child App script is evicted from server loader cache, we get a small memory leak,
|
|
27
|
+
// because providers in singleton child DI, page components / actions, will store a reference to removed script,
|
|
28
|
+
// and server loader cache will contain a new instance of the same script.
|
|
29
|
+
//
|
|
30
|
+
// So, it is better to have bigger cache size to prevent evicting from cache,
|
|
31
|
+
// also for one Child App we need to save 3 elements - server JS, stats JSON and loadable stats JSON.
|
|
32
|
+
//
|
|
33
|
+
// TODO: cache cleanup for previous versions of Child Apps
|
|
34
|
+
max: 100,
|
|
35
|
+
...cacheOptions,
|
|
22
36
|
});
|
|
23
|
-
|
|
37
|
+
let internalLoadCache = cache;
|
|
38
|
+
// Cache is not compatible with HMR (Hot Module Replacement) because after HMR and page reload,
|
|
39
|
+
// we get the page from the cache. To solve this, we use Async Local Storage to ensure the
|
|
40
|
+
// cache is only valid within the context of a single request.
|
|
41
|
+
if (process.env.NODE_ENV === 'development' && !!asyncLocalStorage) {
|
|
42
|
+
internalLoadCache = {
|
|
43
|
+
get(key) {
|
|
44
|
+
if (key?.startsWith('__DEBUG__')) {
|
|
45
|
+
const store = asyncLocalStorage.getStore();
|
|
46
|
+
if (store) {
|
|
47
|
+
return store[key];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return cache.get(key);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
set(key, module) {
|
|
55
|
+
if (key?.startsWith('__DEBUG__')) {
|
|
56
|
+
const store = asyncLocalStorage.getStore();
|
|
57
|
+
if (store) {
|
|
58
|
+
store[key] = module;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
cache.set(key, module);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
24
67
|
this.log = logger('child-app:loader');
|
|
25
68
|
this.loader = new moduleLoaderServer.ServerLoader({
|
|
26
|
-
cache,
|
|
69
|
+
cache: internalLoadCache,
|
|
27
70
|
log: this.log,
|
|
28
71
|
requestOptions: {
|
|
29
72
|
circuitBreakerEnabled: isNil__default["default"](envManager.get('HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED')),
|
|
30
73
|
},
|
|
31
74
|
});
|
|
75
|
+
this.loadModuleHook = this.hookFactory.createAsync('childAppLoadModule');
|
|
76
|
+
this.loadModuleHook.tapPromise('childAppLoadModule', async (_, payload) => {
|
|
77
|
+
return this.loadModule(payload);
|
|
78
|
+
});
|
|
79
|
+
plugins?.forEach((plugin) => {
|
|
80
|
+
plugin.apply({ loadModule: this.loadModuleHook });
|
|
81
|
+
});
|
|
32
82
|
}
|
|
33
|
-
async
|
|
83
|
+
async loadModule({ config }) {
|
|
34
84
|
const promises = [
|
|
35
85
|
this.loader.resolveByUrl(config.server.entry, {
|
|
36
86
|
codePrefix: `var ASSETS_PREFIX="${config.client.baseUrl}";`,
|
|
@@ -61,15 +111,12 @@ class ServerLoader extends loader.Loader {
|
|
|
61
111
|
}
|
|
62
112
|
await Promise.all(promises);
|
|
63
113
|
await this.init(config);
|
|
64
|
-
if (config.tag === 'debug') {
|
|
65
|
-
setTimeout(() => {
|
|
66
|
-
this.internalLoadCache.set(config.server.entry, null);
|
|
67
|
-
this.internalLoadCache.set(config.client.stats, null);
|
|
68
|
-
this.internalLoadCache.set(config.client.statsLoadable, null);
|
|
69
|
-
}, 10000);
|
|
70
|
-
}
|
|
71
114
|
return this.get(config);
|
|
72
115
|
}
|
|
116
|
+
async load(config) {
|
|
117
|
+
const childApp = await this.loadModuleHook.callPromise({ config });
|
|
118
|
+
return childApp;
|
|
119
|
+
}
|
|
73
120
|
async init(config) {
|
|
74
121
|
const container = this.loader.getByUrl(config.server.entry);
|
|
75
122
|
if (!container) {
|
|
@@ -95,6 +142,9 @@ class ServerLoader extends loader.Loader {
|
|
|
95
142
|
}
|
|
96
143
|
get(config) {
|
|
97
144
|
const container = this.loader.getByUrl(config.server.entry);
|
|
145
|
+
if (!container) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
98
148
|
const entry = container && this.initializedMap.get(container);
|
|
99
149
|
return entry && this.resolve(entry);
|
|
100
150
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SharedModule, SharedScopeItem } from './utils';
|
|
2
|
+
export type SharedModuleWithChunks = {
|
|
3
|
+
shareKey: string;
|
|
4
|
+
from: string;
|
|
5
|
+
version: string;
|
|
6
|
+
eager: boolean;
|
|
7
|
+
childAppName?: string;
|
|
8
|
+
childAppVersion?: string;
|
|
9
|
+
chunks?: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare function resolveBestLoadedSharedModules({ sharedModules, sharedScopeItems, }: {
|
|
12
|
+
sharedModules: SharedModule[];
|
|
13
|
+
sharedScopeItems: SharedScopeItem[];
|
|
14
|
+
}): SharedModuleWithChunks[];
|
|
15
|
+
//# sourceMappingURL=best-loaded-shared-modules.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function resolveBestLoadedSharedModules({ sharedModules, sharedScopeItems, }) {
|
|
2
|
+
const result = [];
|
|
3
|
+
for (const sharedScopeItem of sharedScopeItems) {
|
|
4
|
+
const { shareKey, from, eager, loaded } = sharedScopeItem;
|
|
5
|
+
// we need only Child Apps deps, host app shared modules is always loaded on the client
|
|
6
|
+
// and we need to get only used shared modules, `loaded` flag means that module was required by MF runtime
|
|
7
|
+
// https://github.com/webpack/webpack/blob/97d4961cd1de9c69dba0f050a63f3b56bb64fab2/lib/sharing/ConsumeSharedRuntimeModule.js#L104
|
|
8
|
+
if (from.startsWith('child-app') && !!loaded) {
|
|
9
|
+
const sharedModule = sharedModules.find((m) => m.from === from && m.provides?.[0]?.shareKey === shareKey);
|
|
10
|
+
if (sharedModule) {
|
|
11
|
+
result.push({
|
|
12
|
+
shareKey,
|
|
13
|
+
from: sharedScopeItem.from,
|
|
14
|
+
eager,
|
|
15
|
+
version: sharedScopeItem.version,
|
|
16
|
+
childAppName: sharedModule?.childAppName,
|
|
17
|
+
childAppVersion: sharedModule?.childAppVersion,
|
|
18
|
+
chunks: sharedModule?.chunks,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { resolveBestLoadedSharedModules };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
function resolveBestLoadedSharedModules({ sharedModules, sharedScopeItems, }) {
|
|
6
|
+
const result = [];
|
|
7
|
+
for (const sharedScopeItem of sharedScopeItems) {
|
|
8
|
+
const { shareKey, from, eager, loaded } = sharedScopeItem;
|
|
9
|
+
// we need only Child Apps deps, host app shared modules is always loaded on the client
|
|
10
|
+
// and we need to get only used shared modules, `loaded` flag means that module was required by MF runtime
|
|
11
|
+
// https://github.com/webpack/webpack/blob/97d4961cd1de9c69dba0f050a63f3b56bb64fab2/lib/sharing/ConsumeSharedRuntimeModule.js#L104
|
|
12
|
+
if (from.startsWith('child-app') && !!loaded) {
|
|
13
|
+
const sharedModule = sharedModules.find((m) => m.from === from && m.provides?.[0]?.shareKey === shareKey);
|
|
14
|
+
if (sharedModule) {
|
|
15
|
+
result.push({
|
|
16
|
+
shareKey,
|
|
17
|
+
from: sharedScopeItem.from,
|
|
18
|
+
eager,
|
|
19
|
+
version: sharedScopeItem.version,
|
|
20
|
+
childAppName: sharedModule?.childAppName,
|
|
21
|
+
childAppVersion: sharedModule?.childAppVersion,
|
|
22
|
+
chunks: sharedModule?.chunks,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.resolveBestLoadedSharedModules = resolveBestLoadedSharedModules;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SharedModule, SharedScopeItem } from './utils';
|
|
2
|
+
export type SharedModuleWithChunks = {
|
|
3
|
+
shareKey: string;
|
|
4
|
+
from: string;
|
|
5
|
+
version: string;
|
|
6
|
+
eager: boolean;
|
|
7
|
+
childAppName?: string;
|
|
8
|
+
childAppVersion?: string;
|
|
9
|
+
chunks?: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare function resolveBestSharedModules({ sharedModules, sharedScopeItems, }: {
|
|
12
|
+
sharedModules: SharedModule[];
|
|
13
|
+
sharedScopeItems: SharedScopeItem[];
|
|
14
|
+
}): SharedModuleWithChunks[];
|
|
15
|
+
//# sourceMappingURL=best-shared-modules.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChildAppFinalConfig } from '@tramvai/tokens-child-app';
|
|
2
|
+
import { ModuleFederationSharedModule, ModuleFederationSharedScope, ModuleFederationSharedScopeItem } from '../../shared/webpack/moduleFederation';
|
|
3
|
+
import { ServerLoader } from '../loader';
|
|
4
|
+
export type SharedScopeItem = ModuleFederationSharedScopeItem & {
|
|
5
|
+
shareKey: string;
|
|
6
|
+
version: string;
|
|
7
|
+
};
|
|
8
|
+
export type SharedModule = ModuleFederationSharedModule & {
|
|
9
|
+
from: string;
|
|
10
|
+
childAppName: string;
|
|
11
|
+
childAppVersion: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function getFlatSharedScopeItemsList(sharedScope: ModuleFederationSharedScope): SharedScopeItem[];
|
|
14
|
+
export declare function getFlatSharedModulesList({ preloadedConfigs, loader, }: {
|
|
15
|
+
preloadedConfigs: ChildAppFinalConfig[];
|
|
16
|
+
loader: ServerLoader;
|
|
17
|
+
}): SharedModule[];
|
|
18
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function getFlatSharedScopeItemsList(sharedScope) {
|
|
2
|
+
// flat list of all shared items initialized in shared scope
|
|
3
|
+
const sharedScopeItems = [];
|
|
4
|
+
for (const shareKey in sharedScope) {
|
|
5
|
+
const sharedDependency = sharedScope[shareKey];
|
|
6
|
+
for (const version in sharedDependency) {
|
|
7
|
+
const sharedScopeItem = sharedDependency[version];
|
|
8
|
+
sharedScopeItems.push({
|
|
9
|
+
...sharedScopeItem,
|
|
10
|
+
shareKey,
|
|
11
|
+
version,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return sharedScopeItems;
|
|
16
|
+
}
|
|
17
|
+
function getFlatSharedModulesList({ preloadedConfigs, loader, }) {
|
|
18
|
+
const sharedModules = [];
|
|
19
|
+
for (const config of preloadedConfigs) {
|
|
20
|
+
const stats = 'getStats' in loader ? loader.getStats(config) : undefined;
|
|
21
|
+
const from = `child-app:${config.name}:${config.version}`;
|
|
22
|
+
if (stats && stats.federatedModules) {
|
|
23
|
+
for (const federatedModule of stats.federatedModules) {
|
|
24
|
+
for (const sharedModule of federatedModule.sharedModules) {
|
|
25
|
+
sharedModules.push({
|
|
26
|
+
...sharedModule,
|
|
27
|
+
from,
|
|
28
|
+
childAppName: config.name,
|
|
29
|
+
childAppVersion: config.version,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return sharedModules;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { getFlatSharedModulesList, getFlatSharedScopeItemsList };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
function getFlatSharedScopeItemsList(sharedScope) {
|
|
6
|
+
// flat list of all shared items initialized in shared scope
|
|
7
|
+
const sharedScopeItems = [];
|
|
8
|
+
for (const shareKey in sharedScope) {
|
|
9
|
+
const sharedDependency = sharedScope[shareKey];
|
|
10
|
+
for (const version in sharedDependency) {
|
|
11
|
+
const sharedScopeItem = sharedDependency[version];
|
|
12
|
+
sharedScopeItems.push({
|
|
13
|
+
...sharedScopeItem,
|
|
14
|
+
shareKey,
|
|
15
|
+
version,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return sharedScopeItems;
|
|
20
|
+
}
|
|
21
|
+
function getFlatSharedModulesList({ preloadedConfigs, loader, }) {
|
|
22
|
+
const sharedModules = [];
|
|
23
|
+
for (const config of preloadedConfigs) {
|
|
24
|
+
const stats = 'getStats' in loader ? loader.getStats(config) : undefined;
|
|
25
|
+
const from = `child-app:${config.name}:${config.version}`;
|
|
26
|
+
if (stats && stats.federatedModules) {
|
|
27
|
+
for (const federatedModule of stats.federatedModules) {
|
|
28
|
+
for (const sharedModule of federatedModule.sharedModules) {
|
|
29
|
+
sharedModules.push({
|
|
30
|
+
...sharedModule,
|
|
31
|
+
from,
|
|
32
|
+
childAppName: config.name,
|
|
33
|
+
childAppVersion: config.version,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return sharedModules;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.getFlatSharedModulesList = getFlatSharedModulesList;
|
|
43
|
+
exports.getFlatSharedScopeItemsList = getFlatSharedScopeItemsList;
|
package/lib/server/preload.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Route } from '@tinkoff/router';
|
|
2
|
-
import {
|
|
2
|
+
import { AsyncTapableHookInstance, TAPABLE_HOOK_FACTORY_TOKEN } from '@tramvai/core';
|
|
3
|
+
import { type ChildAppCommandLineRunner, type ChildAppRequestConfig, type ChildAppLoader, type ChildAppPreloadManager, type ChildAppStateManager, type CHILD_APP_RESOLVE_CONFIG_TOKEN, type ChildAppFinalConfig, type CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, type CHILD_APP_DI_MANAGER_TOKEN, CHILD_APP_PRELOAD_MANAGER_PLUGIN, PreloadArgs, RunChildAppCommandLineArgs } from '@tramvai/tokens-child-app';
|
|
3
4
|
export declare class PreloadManager implements ChildAppPreloadManager {
|
|
4
5
|
private loader;
|
|
5
6
|
private runner;
|
|
@@ -10,14 +11,24 @@ export declare class PreloadManager implements ChildAppPreloadManager {
|
|
|
10
11
|
private shouldRunImmediately;
|
|
11
12
|
private map;
|
|
12
13
|
private preloadMap;
|
|
13
|
-
|
|
14
|
+
private hookFactory;
|
|
15
|
+
hooks: {
|
|
16
|
+
preloadChildApp: AsyncTapableHookInstance<PreloadArgs>;
|
|
17
|
+
prefetchChildApp: AsyncTapableHookInstance<PreloadArgs>;
|
|
18
|
+
runChildAppCommandLine: AsyncTapableHookInstance<RunChildAppCommandLineArgs>;
|
|
19
|
+
};
|
|
20
|
+
constructor({ loader, runner, stateManager, resolutionConfigManager, resolveFullConfig, diManager, hookFactory, plugins, }: {
|
|
14
21
|
loader: ChildAppLoader;
|
|
15
22
|
runner: ChildAppCommandLineRunner;
|
|
16
23
|
stateManager: ChildAppStateManager;
|
|
17
24
|
resolutionConfigManager: typeof CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN;
|
|
18
25
|
resolveFullConfig: typeof CHILD_APP_RESOLVE_CONFIG_TOKEN;
|
|
19
26
|
diManager: typeof CHILD_APP_DI_MANAGER_TOKEN;
|
|
27
|
+
hookFactory: typeof TAPABLE_HOOK_FACTORY_TOKEN;
|
|
28
|
+
plugins: (typeof CHILD_APP_PRELOAD_MANAGER_PLUGIN)[] | null;
|
|
20
29
|
});
|
|
30
|
+
private runChildAppCommandLineHook;
|
|
31
|
+
private preloadChildAppHook;
|
|
21
32
|
preload(request: ChildAppRequestConfig, route?: Route): Promise<void>;
|
|
22
33
|
prefetch(request: ChildAppRequestConfig, route?: Route): Promise<void>;
|
|
23
34
|
isPreloaded(request: ChildAppRequestConfig): boolean;
|
package/lib/server/preload.es.js
CHANGED
|
@@ -2,28 +2,53 @@ import { optional } from '@tinkoff/dippy';
|
|
|
2
2
|
import { CHILD_APP_PAGE_SERVICE_TOKEN } from '@tramvai/tokens-child-app';
|
|
3
3
|
|
|
4
4
|
class PreloadManager {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
loader;
|
|
6
|
+
runner;
|
|
7
|
+
stateManager;
|
|
8
|
+
resolutionConfigManager;
|
|
9
|
+
resolveFullConfig;
|
|
10
|
+
diManager;
|
|
11
|
+
shouldRunImmediately = false;
|
|
12
|
+
map = new Map();
|
|
13
|
+
preloadMap = new Map();
|
|
14
|
+
hookFactory;
|
|
15
|
+
hooks;
|
|
16
|
+
constructor({ loader, runner, stateManager, resolutionConfigManager, resolveFullConfig, diManager, hookFactory, plugins, }) {
|
|
9
17
|
this.loader = loader;
|
|
10
18
|
this.runner = runner;
|
|
11
19
|
this.stateManager = stateManager;
|
|
12
20
|
this.resolutionConfigManager = resolutionConfigManager;
|
|
13
21
|
this.resolveFullConfig = resolveFullConfig;
|
|
14
22
|
this.diManager = diManager;
|
|
23
|
+
this.hookFactory = hookFactory;
|
|
24
|
+
this.hooks = {
|
|
25
|
+
preloadChildApp: this.hookFactory.createAsync('preloadChildApp'),
|
|
26
|
+
prefetchChildApp: this.hookFactory.createAsync('prefetchChildApp'),
|
|
27
|
+
runChildAppCommandLine: this.hookFactory.createAsync('runChildAppCommandLine'),
|
|
28
|
+
};
|
|
29
|
+
this.hooks.preloadChildApp.tapPromise('childAppPreload', async (_, payload) => {
|
|
30
|
+
await this.preloadChildAppHook(payload);
|
|
31
|
+
});
|
|
32
|
+
this.hooks.prefetchChildApp.tapPromise('childAppPrefetch', async () => {
|
|
33
|
+
// do nothing at server side
|
|
34
|
+
});
|
|
35
|
+
this.hooks.runChildAppCommandLine.tapPromise('childAppCommandRun', async (_, payload) => {
|
|
36
|
+
await this.runChildAppCommandLineHook(payload);
|
|
37
|
+
});
|
|
38
|
+
plugins?.forEach((plugin) => {
|
|
39
|
+
plugin.apply(this.hooks);
|
|
40
|
+
});
|
|
15
41
|
}
|
|
16
|
-
async
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (!config) {
|
|
42
|
+
async runChildAppCommandLineHook({ config, status, }) {
|
|
43
|
+
const childApp = this.loader.get(config);
|
|
44
|
+
if (!childApp) {
|
|
20
45
|
return;
|
|
21
46
|
}
|
|
47
|
+
await this.runner.run('server', status, config);
|
|
48
|
+
await this.stateManager.registerChildApp(config);
|
|
49
|
+
}
|
|
50
|
+
async preloadChildAppHook({ config }) {
|
|
22
51
|
const { key } = config;
|
|
23
|
-
if (this.map.has(key)) {
|
|
24
|
-
await this.map.get(key);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
52
|
const promise = this.loader
|
|
28
53
|
.load(config)
|
|
29
54
|
.catch(() => {
|
|
@@ -47,8 +72,23 @@ class PreloadManager {
|
|
|
47
72
|
await promise;
|
|
48
73
|
}
|
|
49
74
|
}
|
|
75
|
+
async preload(request, route) {
|
|
76
|
+
await this.resolutionConfigManager.init();
|
|
77
|
+
const config = this.resolveFullConfig(request);
|
|
78
|
+
if (!config) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const { key } = config;
|
|
82
|
+
if (this.map.has(key)) {
|
|
83
|
+
await this.map.get(key);
|
|
84
|
+
}
|
|
85
|
+
await this.hooks.preloadChildApp.callPromise({
|
|
86
|
+
config,
|
|
87
|
+
route,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
50
90
|
async prefetch(request, route) {
|
|
51
|
-
// do nothing
|
|
91
|
+
// do nothing on server side
|
|
52
92
|
}
|
|
53
93
|
isPreloaded(request) {
|
|
54
94
|
const config = this.resolveFullConfig(request);
|
|
@@ -78,12 +118,11 @@ class PreloadManager {
|
|
|
78
118
|
return Array.from(this.preloadMap.values());
|
|
79
119
|
}
|
|
80
120
|
async run(status, config) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
await this.stateManager.registerChildApp(config);
|
|
121
|
+
await this.hooks.runChildAppCommandLine.callPromise({
|
|
122
|
+
config,
|
|
123
|
+
status,
|
|
124
|
+
line: 'server',
|
|
125
|
+
});
|
|
87
126
|
}
|
|
88
127
|
saveNotPreloadedForSpaNavigation(request) {
|
|
89
128
|
// do nothing at server-side
|
package/lib/server/preload.js
CHANGED
|
@@ -6,28 +6,53 @@ var dippy = require('@tinkoff/dippy');
|
|
|
6
6
|
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
7
7
|
|
|
8
8
|
class PreloadManager {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
loader;
|
|
10
|
+
runner;
|
|
11
|
+
stateManager;
|
|
12
|
+
resolutionConfigManager;
|
|
13
|
+
resolveFullConfig;
|
|
14
|
+
diManager;
|
|
15
|
+
shouldRunImmediately = false;
|
|
16
|
+
map = new Map();
|
|
17
|
+
preloadMap = new Map();
|
|
18
|
+
hookFactory;
|
|
19
|
+
hooks;
|
|
20
|
+
constructor({ loader, runner, stateManager, resolutionConfigManager, resolveFullConfig, diManager, hookFactory, plugins, }) {
|
|
13
21
|
this.loader = loader;
|
|
14
22
|
this.runner = runner;
|
|
15
23
|
this.stateManager = stateManager;
|
|
16
24
|
this.resolutionConfigManager = resolutionConfigManager;
|
|
17
25
|
this.resolveFullConfig = resolveFullConfig;
|
|
18
26
|
this.diManager = diManager;
|
|
27
|
+
this.hookFactory = hookFactory;
|
|
28
|
+
this.hooks = {
|
|
29
|
+
preloadChildApp: this.hookFactory.createAsync('preloadChildApp'),
|
|
30
|
+
prefetchChildApp: this.hookFactory.createAsync('prefetchChildApp'),
|
|
31
|
+
runChildAppCommandLine: this.hookFactory.createAsync('runChildAppCommandLine'),
|
|
32
|
+
};
|
|
33
|
+
this.hooks.preloadChildApp.tapPromise('childAppPreload', async (_, payload) => {
|
|
34
|
+
await this.preloadChildAppHook(payload);
|
|
35
|
+
});
|
|
36
|
+
this.hooks.prefetchChildApp.tapPromise('childAppPrefetch', async () => {
|
|
37
|
+
// do nothing at server side
|
|
38
|
+
});
|
|
39
|
+
this.hooks.runChildAppCommandLine.tapPromise('childAppCommandRun', async (_, payload) => {
|
|
40
|
+
await this.runChildAppCommandLineHook(payload);
|
|
41
|
+
});
|
|
42
|
+
plugins?.forEach((plugin) => {
|
|
43
|
+
plugin.apply(this.hooks);
|
|
44
|
+
});
|
|
19
45
|
}
|
|
20
|
-
async
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!config) {
|
|
46
|
+
async runChildAppCommandLineHook({ config, status, }) {
|
|
47
|
+
const childApp = this.loader.get(config);
|
|
48
|
+
if (!childApp) {
|
|
24
49
|
return;
|
|
25
50
|
}
|
|
51
|
+
await this.runner.run('server', status, config);
|
|
52
|
+
await this.stateManager.registerChildApp(config);
|
|
53
|
+
}
|
|
54
|
+
async preloadChildAppHook({ config }) {
|
|
26
55
|
const { key } = config;
|
|
27
|
-
if (this.map.has(key)) {
|
|
28
|
-
await this.map.get(key);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
56
|
const promise = this.loader
|
|
32
57
|
.load(config)
|
|
33
58
|
.catch(() => {
|
|
@@ -51,8 +76,23 @@ class PreloadManager {
|
|
|
51
76
|
await promise;
|
|
52
77
|
}
|
|
53
78
|
}
|
|
79
|
+
async preload(request, route) {
|
|
80
|
+
await this.resolutionConfigManager.init();
|
|
81
|
+
const config = this.resolveFullConfig(request);
|
|
82
|
+
if (!config) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { key } = config;
|
|
86
|
+
if (this.map.has(key)) {
|
|
87
|
+
await this.map.get(key);
|
|
88
|
+
}
|
|
89
|
+
await this.hooks.preloadChildApp.callPromise({
|
|
90
|
+
config,
|
|
91
|
+
route,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
54
94
|
async prefetch(request, route) {
|
|
55
|
-
// do nothing
|
|
95
|
+
// do nothing on server side
|
|
56
96
|
}
|
|
57
97
|
isPreloaded(request) {
|
|
58
98
|
const config = this.resolveFullConfig(request);
|
|
@@ -82,12 +122,11 @@ class PreloadManager {
|
|
|
82
122
|
return Array.from(this.preloadMap.values());
|
|
83
123
|
}
|
|
84
124
|
async run(status, config) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
await this.stateManager.registerChildApp(config);
|
|
125
|
+
await this.hooks.runChildAppCommandLine.callPromise({
|
|
126
|
+
config,
|
|
127
|
+
status,
|
|
128
|
+
line: 'server',
|
|
129
|
+
});
|
|
91
130
|
}
|
|
92
131
|
saveNotPreloadedForSpaNavigation(request) {
|
|
93
132
|
// do nothing at server-side
|