@tramvai/module-child-app 5.50.0 → 5.53.78
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
|
@@ -6,14 +6,24 @@ const getModuleFromGlobal = (entry) => {
|
|
|
6
6
|
return window[`child-app__${entry}`];
|
|
7
7
|
};
|
|
8
8
|
class BrowserLoader extends Loader {
|
|
9
|
-
|
|
9
|
+
log;
|
|
10
|
+
initializedMap = new WeakMap();
|
|
11
|
+
map = new Map();
|
|
12
|
+
hookFactory;
|
|
13
|
+
loadModuleHook;
|
|
14
|
+
constructor({ logger, hookFactory, plugins, }) {
|
|
10
15
|
super();
|
|
11
|
-
this.
|
|
12
|
-
this.map = new Map();
|
|
16
|
+
this.hookFactory = hookFactory;
|
|
13
17
|
this.log = logger('child-app:loader');
|
|
18
|
+
this.loadModuleHook = this.hookFactory.createAsync('childAppLoadModule');
|
|
19
|
+
this.loadModuleHook.tapPromise('childAppLoadModule', async (_, { config }) => {
|
|
20
|
+
return this.loadModule({ config });
|
|
21
|
+
});
|
|
22
|
+
plugins?.forEach((plugin) => {
|
|
23
|
+
plugin.apply({ loadModule: this.loadModuleHook });
|
|
24
|
+
});
|
|
14
25
|
}
|
|
15
|
-
|
|
16
|
-
async load(config) {
|
|
26
|
+
async loadModule({ config }) {
|
|
17
27
|
const moduleName = config.name;
|
|
18
28
|
const childApp = await this.get(config);
|
|
19
29
|
if (childApp) {
|
|
@@ -63,6 +73,9 @@ class BrowserLoader extends Loader {
|
|
|
63
73
|
});
|
|
64
74
|
return Promise.reject(new Error(`Error resolving child-app ${moduleName}`));
|
|
65
75
|
}
|
|
76
|
+
async load(config) {
|
|
77
|
+
return this.loadModuleHook.callPromise({ config });
|
|
78
|
+
}
|
|
66
79
|
async init(config) {
|
|
67
80
|
const container = getModuleFromGlobal(config.client.entry);
|
|
68
81
|
if (container) {
|
package/lib/browser/loader.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChildApp } from '@tramvai/child-app-core';
|
|
2
|
-
import type { ChildAppFinalConfig } from '@tramvai/tokens-child-app';
|
|
2
|
+
import type { CHILD_APP_LOADER_PLUGIN, ChildAppFinalConfig } from '@tramvai/tokens-child-app';
|
|
3
3
|
import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
4
|
+
import { AsyncTapableHookInstance, TAPABLE_HOOK_FACTORY_TOKEN } from '@tramvai/core';
|
|
4
5
|
import { Loader } from '../shared/loader';
|
|
5
6
|
import type { ModuleFederationContainer } from '../shared/webpack/moduleFederation';
|
|
6
7
|
export declare const getModuleFromGlobal: (entry: string) => ModuleFederationContainer | undefined;
|
|
@@ -8,9 +9,16 @@ export declare class BrowserLoader extends Loader {
|
|
|
8
9
|
private readonly log;
|
|
9
10
|
private readonly initializedMap;
|
|
10
11
|
private map;
|
|
11
|
-
|
|
12
|
+
private hookFactory;
|
|
13
|
+
loadModuleHook: AsyncTapableHookInstance<{
|
|
14
|
+
config: ChildAppFinalConfig;
|
|
15
|
+
}, ChildApp | undefined>;
|
|
16
|
+
constructor({ logger, hookFactory, plugins, }: {
|
|
12
17
|
logger: typeof LOGGER_TOKEN;
|
|
18
|
+
hookFactory: typeof TAPABLE_HOOK_FACTORY_TOKEN;
|
|
19
|
+
plugins: (typeof CHILD_APP_LOADER_PLUGIN)[] | null;
|
|
13
20
|
});
|
|
21
|
+
private loadModule;
|
|
14
22
|
load(config: ChildAppFinalConfig): Promise<ChildApp | undefined>;
|
|
15
23
|
init(config: ChildAppFinalConfig): Promise<void>;
|
|
16
24
|
get(config: ChildAppFinalConfig): ChildApp | undefined;
|
|
@@ -1,23 +1,76 @@
|
|
|
1
1
|
import { CHILD_APP_PAGE_SERVICE_TOKEN } from '@tramvai/tokens-child-app';
|
|
2
2
|
import { optional } from '@tinkoff/dippy';
|
|
3
|
-
import { ChildAppStore } from '../shared/store.browser.js';
|
|
3
|
+
import { setChildAppPreloadStatusOnClient, ChildAppStore } from '../shared/store.browser.js';
|
|
4
4
|
import { getModuleFromGlobal } from './loader.browser.js';
|
|
5
5
|
|
|
6
6
|
class PreloadManager {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
loader;
|
|
8
|
+
runner;
|
|
9
|
+
store;
|
|
10
|
+
resolutionConfigManager;
|
|
11
|
+
resolveExternalConfig;
|
|
12
|
+
diManager;
|
|
13
|
+
pageHasRendered = false;
|
|
14
|
+
pageHasLoaded = false;
|
|
15
|
+
currentlyPreloaded = new Map();
|
|
16
|
+
hasPreloadBefore = new Set();
|
|
17
|
+
notPreloadedForCurrentSpaNavigation = new Set();
|
|
18
|
+
hasInitialized = false;
|
|
19
|
+
map = new Map();
|
|
20
|
+
hookFactory;
|
|
21
|
+
hooks;
|
|
22
|
+
constructor({ loader, runner, resolutionConfigManager, resolveExternalConfig, store, diManager, hookFactory, plugins, }) {
|
|
15
23
|
this.loader = loader;
|
|
16
24
|
this.runner = runner;
|
|
17
25
|
this.store = store;
|
|
18
26
|
this.resolutionConfigManager = resolutionConfigManager;
|
|
19
27
|
this.resolveExternalConfig = resolveExternalConfig;
|
|
20
28
|
this.diManager = diManager;
|
|
29
|
+
this.hookFactory = hookFactory;
|
|
30
|
+
this.hooks = {
|
|
31
|
+
preloadChildApp: this.hookFactory.createAsync('preloadChildApp'),
|
|
32
|
+
prefetchChildApp: this.hookFactory.createAsync('prefetchChildApp'),
|
|
33
|
+
runChildAppCommandLine: this.hookFactory.createAsync('runChildAppCommandLine'),
|
|
34
|
+
};
|
|
35
|
+
this.hooks.prefetchChildApp.tapPromise('prefetchChildApp', async (_, payload) => {
|
|
36
|
+
await this.prefetchChildAppHook(payload);
|
|
37
|
+
});
|
|
38
|
+
this.hooks.preloadChildApp.tapPromise('preloadChildApp', async (_, payload) => {
|
|
39
|
+
await this.preloadChildAppHook(payload);
|
|
40
|
+
});
|
|
41
|
+
this.hooks.runChildAppCommandLine.tapPromise('runChildAppCommandLine', async (_, payload) => {
|
|
42
|
+
await this.runChildAppCommandLineHook(payload);
|
|
43
|
+
});
|
|
44
|
+
plugins?.forEach((plugin) => {
|
|
45
|
+
plugin.apply(this.hooks);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async runChildAppCommandLineHook({ status, config, }) {
|
|
49
|
+
const childApp = this.loader.get(config);
|
|
50
|
+
if (!childApp) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
await this.runner.run('client', status, config);
|
|
54
|
+
}
|
|
55
|
+
async prefetchChildAppHook({ config, route, }) {
|
|
56
|
+
await this.loader.load(config);
|
|
57
|
+
await this.resolveComponent(config, route);
|
|
58
|
+
}
|
|
59
|
+
async preloadChildAppHook({ config, route, }) {
|
|
60
|
+
await this.loader.load(config);
|
|
61
|
+
await this.resolveComponent(config, route);
|
|
62
|
+
await this.run('customer', config);
|
|
63
|
+
// do not block Child App preloading by "clear" stage (where actions executed),
|
|
64
|
+
// because in will delay Child App rendering
|
|
65
|
+
// TODO: do we need to wait this Child App stage in "afterSpaTransition"?
|
|
66
|
+
// TODO: Can be a race condition between Child App render and actions?
|
|
67
|
+
this.run('clear', config).catch((error) => {
|
|
68
|
+
if (process.env.NODE_ENV === 'development') {
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.error('Child App command line error', error);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
this.hasPreloadBefore.add(config.key);
|
|
21
74
|
}
|
|
22
75
|
async preload(request, route) {
|
|
23
76
|
await this.init();
|
|
@@ -40,27 +93,30 @@ class PreloadManager {
|
|
|
40
93
|
// but in case render has happened load child-app as soon as possible
|
|
41
94
|
const promise = (async () => {
|
|
42
95
|
try {
|
|
43
|
-
await this.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// do not block Child App preloading by "clear" stage (where actions executed),
|
|
47
|
-
// because in will delay Child App rendering
|
|
48
|
-
// TODO: do we need to wait this Child App stage in "afterSpaTransition"?
|
|
49
|
-
// TODO: Can be a race condition between Child App render and actions?
|
|
50
|
-
this.run('clear', config).catch((error) => {
|
|
51
|
-
if (process.env.NODE_ENV === 'development') {
|
|
52
|
-
// eslint-disable-next-line no-console
|
|
53
|
-
console.error('Child App command line error', error);
|
|
54
|
-
}
|
|
96
|
+
await this.hooks.preloadChildApp.callPromise({
|
|
97
|
+
config,
|
|
98
|
+
route,
|
|
55
99
|
});
|
|
100
|
+
this.store.dispatch(setChildAppPreloadStatusOnClient({
|
|
101
|
+
[key]: {
|
|
102
|
+
status: 'loaded',
|
|
103
|
+
},
|
|
104
|
+
}));
|
|
56
105
|
}
|
|
57
106
|
catch (error) {
|
|
58
107
|
if (process.env.NODE_ENV === 'development') {
|
|
59
108
|
// eslint-disable-next-line no-console
|
|
60
109
|
console.error('Child App loading error', error);
|
|
61
110
|
}
|
|
111
|
+
this.hasPreloadBefore.delete(config.key);
|
|
112
|
+
this.map.delete(config.key);
|
|
113
|
+
this.store.dispatch(setChildAppPreloadStatusOnClient({
|
|
114
|
+
[key]: {
|
|
115
|
+
status: 'error',
|
|
116
|
+
},
|
|
117
|
+
}));
|
|
118
|
+
return Promise.reject(error);
|
|
62
119
|
}
|
|
63
|
-
this.hasPreloadBefore.add(key);
|
|
64
120
|
})();
|
|
65
121
|
this.map.set(key, promise);
|
|
66
122
|
return promise;
|
|
@@ -79,14 +135,14 @@ class PreloadManager {
|
|
|
79
135
|
}
|
|
80
136
|
if (!this.isPreloaded(config)) {
|
|
81
137
|
try {
|
|
82
|
-
await this.
|
|
83
|
-
await this.resolveComponent(config, route);
|
|
138
|
+
await this.hooks.prefetchChildApp.callPromise({ config, route });
|
|
84
139
|
}
|
|
85
140
|
catch (error) {
|
|
86
141
|
if (process.env.NODE_ENV === 'development') {
|
|
87
142
|
// eslint-disable-next-line no-console
|
|
88
143
|
console.error('Child App prefetch error', error);
|
|
89
144
|
}
|
|
145
|
+
return Promise.reject(error);
|
|
90
146
|
}
|
|
91
147
|
}
|
|
92
148
|
}
|
|
@@ -176,11 +232,11 @@ class PreloadManager {
|
|
|
176
232
|
await this.initServerPreloaded();
|
|
177
233
|
}
|
|
178
234
|
async run(status, config) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
235
|
+
await this.hooks.runChildAppCommandLine.callPromise({
|
|
236
|
+
config,
|
|
237
|
+
status,
|
|
238
|
+
line: 'client',
|
|
239
|
+
});
|
|
184
240
|
}
|
|
185
241
|
// preload child app page component - we need to register page actions before running all child app actions
|
|
186
242
|
async resolveComponent(config, route) {
|
package/lib/browser/preload.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type ChildAppCommandLineRunner, type ChildAppRequestConfig, type ChildAppLoader, type ChildAppPreloadManager, type CHILD_APP_RESOLVE_CONFIG_TOKEN, type ChildAppFinalConfig, type CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, type CHILD_APP_DI_MANAGER_TOKEN } from '@tramvai/tokens-child-app';
|
|
1
|
+
import { type ChildAppCommandLineRunner, type ChildAppRequestConfig, type ChildAppLoader, type ChildAppPreloadManager, type CHILD_APP_RESOLVE_CONFIG_TOKEN, type ChildAppFinalConfig, type CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, type CHILD_APP_DI_MANAGER_TOKEN, PreloadArgs, RunChildAppCommandLineArgs, CHILD_APP_PRELOAD_MANAGER_PLUGIN } from '@tramvai/tokens-child-app';
|
|
2
2
|
import type { STORE_TOKEN } from '@tramvai/tokens-common';
|
|
3
3
|
import type { Route } from '@tinkoff/router';
|
|
4
|
+
import { AsyncTapableHookInstance, TAPABLE_HOOK_FACTORY_TOKEN } from '@tramvai/core';
|
|
4
5
|
export declare class PreloadManager implements ChildAppPreloadManager {
|
|
5
6
|
private loader;
|
|
6
7
|
private runner;
|
|
@@ -15,14 +16,25 @@ export declare class PreloadManager implements ChildAppPreloadManager {
|
|
|
15
16
|
private notPreloadedForCurrentSpaNavigation;
|
|
16
17
|
private hasInitialized;
|
|
17
18
|
private map;
|
|
18
|
-
|
|
19
|
+
private hookFactory;
|
|
20
|
+
hooks: {
|
|
21
|
+
preloadChildApp: AsyncTapableHookInstance<PreloadArgs>;
|
|
22
|
+
prefetchChildApp: AsyncTapableHookInstance<PreloadArgs>;
|
|
23
|
+
runChildAppCommandLine: AsyncTapableHookInstance<RunChildAppCommandLineArgs>;
|
|
24
|
+
};
|
|
25
|
+
constructor({ loader, runner, resolutionConfigManager, resolveExternalConfig, store, diManager, hookFactory, plugins, }: {
|
|
19
26
|
loader: ChildAppLoader;
|
|
20
27
|
runner: ChildAppCommandLineRunner;
|
|
21
28
|
resolutionConfigManager: typeof CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN;
|
|
22
29
|
resolveExternalConfig: typeof CHILD_APP_RESOLVE_CONFIG_TOKEN;
|
|
23
30
|
store: typeof STORE_TOKEN;
|
|
24
31
|
diManager: typeof CHILD_APP_DI_MANAGER_TOKEN;
|
|
32
|
+
hookFactory: typeof TAPABLE_HOOK_FACTORY_TOKEN;
|
|
33
|
+
plugins: (typeof CHILD_APP_PRELOAD_MANAGER_PLUGIN)[] | null;
|
|
25
34
|
});
|
|
35
|
+
private runChildAppCommandLineHook;
|
|
36
|
+
private prefetchChildAppHook;
|
|
37
|
+
private preloadChildAppHook;
|
|
26
38
|
preload(request: ChildAppRequestConfig, route?: Route): Promise<void>;
|
|
27
39
|
prefetch(request: ChildAppRequestConfig, route?: Route): Promise<void>;
|
|
28
40
|
isPreloaded(request: ChildAppRequestConfig): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Scope, DI_TOKEN, optional } from '@tinkoff/dippy';
|
|
2
|
-
import { provide, commandLineListTokens } from '@tramvai/core';
|
|
3
|
-
import { CHILD_APP_LOADER_TOKEN, CHILD_APP_PRELOAD_MANAGER_TOKEN, CHILD_APP_COMMAND_LINE_RUNNER_TOKEN, CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, CHILD_APP_RESOLVE_CONFIG_TOKEN, CHILD_APP_DI_MANAGER_TOKEN, CHILD_APP_COMMON_INITIAL_STATE_TOKEN, CHILD_APP_RENDER_MANAGER_TOKEN, CHILD_APP_CONTRACT_MANAGER, HOST_PROVIDED_CONTRACTS, HOST_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
2
|
+
import { provide, TAPABLE_HOOK_FACTORY_TOKEN, commandLineListTokens } from '@tramvai/core';
|
|
3
|
+
import { CHILD_APP_LOADER_TOKEN, CHILD_APP_LOADER_PLUGIN, CHILD_APP_PRELOAD_MANAGER_TOKEN, CHILD_APP_PRELOAD_MANAGER_PLUGIN, CHILD_APP_COMMAND_LINE_RUNNER_TOKEN, CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN, CHILD_APP_RESOLVE_CONFIG_TOKEN, CHILD_APP_DI_MANAGER_TOKEN, CHILD_APP_COMMON_INITIAL_STATE_TOKEN, CHILD_APP_RENDER_MANAGER_TOKEN, CHILD_APP_RENDER_PLUGIN, CHILD_APP_CONTRACT_MANAGER, HOST_PROVIDED_CONTRACTS, HOST_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
4
4
|
import { LOGGER_TOKEN, STORE_TOKEN } from '@tramvai/tokens-common';
|
|
5
5
|
import { ROUTER_TOKEN, PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
6
6
|
import { ChildAppContractManager } from '../contracts/contractManager.browser.browser.js';
|
|
@@ -16,6 +16,11 @@ const browserProviders = [
|
|
|
16
16
|
useClass: BrowserLoader,
|
|
17
17
|
scope: Scope.SINGLETON,
|
|
18
18
|
deps: {
|
|
19
|
+
plugins: {
|
|
20
|
+
optional: true,
|
|
21
|
+
token: CHILD_APP_LOADER_PLUGIN,
|
|
22
|
+
},
|
|
23
|
+
hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
|
|
19
24
|
logger: LOGGER_TOKEN,
|
|
20
25
|
},
|
|
21
26
|
}),
|
|
@@ -23,6 +28,11 @@ const browserProviders = [
|
|
|
23
28
|
provide: CHILD_APP_PRELOAD_MANAGER_TOKEN,
|
|
24
29
|
useClass: PreloadManager,
|
|
25
30
|
deps: {
|
|
31
|
+
plugins: {
|
|
32
|
+
optional: true,
|
|
33
|
+
token: CHILD_APP_PRELOAD_MANAGER_PLUGIN,
|
|
34
|
+
},
|
|
35
|
+
hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
|
|
26
36
|
loader: CHILD_APP_LOADER_TOKEN,
|
|
27
37
|
runner: CHILD_APP_COMMAND_LINE_RUNNER_TOKEN,
|
|
28
38
|
resolutionConfigManager: CHILD_APP_RESOLUTION_CONFIG_MANAGER_TOKEN,
|
|
@@ -39,6 +49,11 @@ const browserProviders = [
|
|
|
39
49
|
provide: CHILD_APP_RENDER_MANAGER_TOKEN,
|
|
40
50
|
useClass: RenderManager,
|
|
41
51
|
deps: {
|
|
52
|
+
plugins: {
|
|
53
|
+
optional: true,
|
|
54
|
+
token: CHILD_APP_RENDER_PLUGIN,
|
|
55
|
+
},
|
|
56
|
+
hookFactory: TAPABLE_HOOK_FACTORY_TOKEN,
|
|
42
57
|
logger: LOGGER_TOKEN,
|
|
43
58
|
diManager: CHILD_APP_DI_MANAGER_TOKEN,
|
|
44
59
|
preloadManager: CHILD_APP_PRELOAD_MANAGER_TOKEN,
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
class RenderManager {
|
|
2
|
-
|
|
2
|
+
preloadManager;
|
|
3
|
+
diManager;
|
|
4
|
+
resolveExternalConfig;
|
|
5
|
+
log;
|
|
6
|
+
hookFactory;
|
|
7
|
+
hooks;
|
|
8
|
+
constructor({ logger, preloadManager, diManager, resolveExternalConfig, hookFactory, plugins, }) {
|
|
9
|
+
this.hookFactory = hookFactory;
|
|
10
|
+
this.hooks = {
|
|
11
|
+
mounted: this.hookFactory.createSync('childAppMounted'),
|
|
12
|
+
mountFailed: this.hookFactory.createSync('childAppMountFailed'),
|
|
13
|
+
};
|
|
3
14
|
this.log = logger('child-app:render');
|
|
4
15
|
this.preloadManager = preloadManager;
|
|
5
16
|
this.diManager = diManager;
|
|
6
17
|
this.resolveExternalConfig = resolveExternalConfig;
|
|
18
|
+
plugins?.forEach((plugin) => {
|
|
19
|
+
plugin.apply(this.hooks);
|
|
20
|
+
});
|
|
7
21
|
}
|
|
8
22
|
getChildDi(request) {
|
|
9
23
|
const config = this.resolveExternalConfig(request);
|
package/lib/browser/render.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import type { Container } from '@tinkoff/dippy';
|
|
2
|
-
import
|
|
2
|
+
import { SyncTapableHookInstance, TAPABLE_HOOK_FACTORY_TOKEN } from '@tramvai/core';
|
|
3
|
+
import type { ChildAppDiManager, ChildAppPreloadManager, ChildAppRenderManager, ChildAppRequestConfig, CHILD_APP_RESOLVE_CONFIG_TOKEN, ChildAppConfigArgs, CHILD_APP_RENDER_PLUGIN } from '@tramvai/tokens-child-app';
|
|
3
4
|
import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
4
5
|
export declare class RenderManager implements ChildAppRenderManager {
|
|
5
6
|
private readonly preloadManager;
|
|
6
7
|
private readonly diManager;
|
|
7
8
|
private readonly resolveExternalConfig;
|
|
8
9
|
private readonly log;
|
|
9
|
-
|
|
10
|
+
private hookFactory;
|
|
11
|
+
hooks: {
|
|
12
|
+
mounted: SyncTapableHookInstance<ChildAppConfigArgs>;
|
|
13
|
+
mountFailed: SyncTapableHookInstance<ChildAppConfigArgs>;
|
|
14
|
+
};
|
|
15
|
+
constructor({ logger, preloadManager, diManager, resolveExternalConfig, hookFactory, plugins, }: {
|
|
10
16
|
logger: typeof LOGGER_TOKEN;
|
|
11
17
|
preloadManager: ChildAppPreloadManager;
|
|
12
18
|
diManager: ChildAppDiManager;
|
|
13
19
|
resolveExternalConfig: typeof CHILD_APP_RESOLVE_CONFIG_TOKEN;
|
|
20
|
+
hookFactory: typeof TAPABLE_HOOK_FACTORY_TOKEN;
|
|
21
|
+
plugins: (typeof CHILD_APP_RENDER_PLUGIN)[] | null;
|
|
14
22
|
});
|
|
15
23
|
getChildDi(request: ChildAppRequestConfig): [Container | undefined, undefined | Promise<Container | undefined>];
|
|
16
24
|
clear(): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const runCommand = async ({ status, forcePreload, runner, preloader,
|
|
1
|
+
const runCommand = async ({ status, forcePreload, runner, preloader, pageService, logger, }) => {
|
|
2
2
|
const childApps = preloader.getPreloadedList();
|
|
3
3
|
const log = logger('child-app:run-preloaded');
|
|
4
4
|
await Promise.all(childApps.map(async (config) => {
|
|
@@ -2,7 +2,7 @@ import type { CHILD_APP_DI_MANAGER_TOKEN } from '@tramvai/tokens-child-app';
|
|
|
2
2
|
import { type CHILD_APP_COMMAND_LINE_RUNNER_TOKEN, type CHILD_APP_PRELOAD_MANAGER_TOKEN } from '@tramvai/tokens-child-app';
|
|
3
3
|
import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
4
4
|
import type { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
5
|
-
export declare const runCommand: ({ status, forcePreload, runner, preloader,
|
|
5
|
+
export declare const runCommand: ({ status, forcePreload, runner, preloader, pageService, logger, }: {
|
|
6
6
|
status: string;
|
|
7
7
|
forcePreload: boolean;
|
|
8
8
|
runner: typeof CHILD_APP_COMMAND_LINE_RUNNER_TOKEN;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { declareModule, provide, Scope } from '@tramvai/core';
|
|
2
|
+
import { CHILD_APP_LOADER_PLUGIN, CHILD_APP_PRELOAD_MANAGER_PLUGIN, CHILD_APP_CONFIG_RESOLUTION_PLUGIN } from '@tramvai/tokens-child-app';
|
|
3
|
+
|
|
4
|
+
const ChildAppMonitoringTimingModule = declareModule({
|
|
5
|
+
name: 'ChildAppMonitoringTiming',
|
|
6
|
+
providers: [
|
|
7
|
+
provide({
|
|
8
|
+
scope: Scope.SINGLETON,
|
|
9
|
+
provide: CHILD_APP_LOADER_PLUGIN,
|
|
10
|
+
useFactory: () => {
|
|
11
|
+
return {
|
|
12
|
+
apply(hooks) {
|
|
13
|
+
hooks.loadModule.wrap(async (_, payload, next) => {
|
|
14
|
+
const childAppName = payload.config.name;
|
|
15
|
+
const startKey = `child-app:load-module:${childAppName}:start`;
|
|
16
|
+
const measureKey = `child-app:load-module:${childAppName}`;
|
|
17
|
+
performance.mark(startKey);
|
|
18
|
+
const childApp = await next(payload);
|
|
19
|
+
const endKey = `child-app:load-module:${childAppName}:end`;
|
|
20
|
+
performance.mark(endKey);
|
|
21
|
+
performance.measure(measureKey, startKey, endKey);
|
|
22
|
+
[startKey, endKey].forEach((name) => performance.clearMarks(name));
|
|
23
|
+
return childApp;
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
29
|
+
provide({
|
|
30
|
+
provide: CHILD_APP_PRELOAD_MANAGER_PLUGIN,
|
|
31
|
+
useFactory: () => {
|
|
32
|
+
return {
|
|
33
|
+
apply(hooks) {
|
|
34
|
+
hooks.prefetchChildApp.wrap(async (_, payload, next) => {
|
|
35
|
+
const childAppName = payload.config.name;
|
|
36
|
+
const startKey = `child-app:prefetch:${childAppName}:start`;
|
|
37
|
+
const endKey = `child-app:prefetch:${childAppName}:end`;
|
|
38
|
+
const measureKey = `child-app:prefetch:${childAppName}`;
|
|
39
|
+
performance.mark(startKey);
|
|
40
|
+
await next(payload);
|
|
41
|
+
performance.mark(endKey);
|
|
42
|
+
performance.measure(measureKey, startKey, endKey);
|
|
43
|
+
[startKey, endKey].forEach((name) => {
|
|
44
|
+
performance.clearMarks(name);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
hooks.preloadChildApp.wrap(async (_, payload, next) => {
|
|
48
|
+
const childAppName = payload.config.name;
|
|
49
|
+
const startKey = `child-app:preload:${childAppName}:start`;
|
|
50
|
+
const endKey = `child-app:preload:${childAppName}:end`;
|
|
51
|
+
const measureKey = `child-app:preload:${childAppName}`;
|
|
52
|
+
performance.mark(startKey);
|
|
53
|
+
await next(payload);
|
|
54
|
+
performance.mark(endKey);
|
|
55
|
+
performance.measure(measureKey, startKey, endKey);
|
|
56
|
+
[startKey, endKey].forEach((name) => {
|
|
57
|
+
performance.clearMarks(name);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
hooks.runChildAppCommandLine.wrap(async (_, payload, next) => {
|
|
61
|
+
const childAppName = payload.config.name;
|
|
62
|
+
const startKey = `child-app:command-line-run:${childAppName}:${payload.line}:${payload.status}:start`;
|
|
63
|
+
const endKey = `child-app:command-line-run:${childAppName}:${payload.line}:${payload.status}:end`;
|
|
64
|
+
const measureKey = `child-app:command-line-run:${childAppName}:${payload.line}:${payload.status}`;
|
|
65
|
+
performance.mark(startKey);
|
|
66
|
+
await next(payload);
|
|
67
|
+
performance.mark(endKey);
|
|
68
|
+
performance.measure(measureKey, startKey, endKey);
|
|
69
|
+
[startKey, endKey].forEach((name) => {
|
|
70
|
+
performance.clearMarks(name);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
provide({
|
|
78
|
+
provide: CHILD_APP_CONFIG_RESOLUTION_PLUGIN,
|
|
79
|
+
useFactory: () => {
|
|
80
|
+
return {
|
|
81
|
+
apply(hooks) {
|
|
82
|
+
hooks.fetchConfig.wrap(async (_, payload, next) => {
|
|
83
|
+
const startKey = `child-app:fetch-config:start`;
|
|
84
|
+
const measureKey = `child-app:fetch-config`;
|
|
85
|
+
performance.mark(startKey);
|
|
86
|
+
const configs = await next(payload);
|
|
87
|
+
const endKey = `child-app:fetch-config:end`;
|
|
88
|
+
performance.mark(endKey);
|
|
89
|
+
performance.measure(measureKey, startKey, endKey);
|
|
90
|
+
[startKey, endKey].forEach((name) => performance.clearMarks(name));
|
|
91
|
+
return configs;
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export { ChildAppMonitoringTimingModule };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const ChildAppMonitoringTimingModule: import("@tinkoff/dippy/lib/modules/module.h").ModuleClass & Partial<import("@tinkoff/dippy/lib/modules/module.h").ModuleSecretParameters> & {
|
|
2
|
+
[x: string]: (...args: any[]) => import("@tramvai/core").ModuleType;
|
|
3
|
+
};
|
|
4
|
+
//# sourceMappingURL=timing.d.ts.map
|
package/lib/browser.js
CHANGED
|
@@ -2,6 +2,7 @@ import { __decorate } from 'tslib';
|
|
|
2
2
|
import { Module } from '@tramvai/core';
|
|
3
3
|
import { sharedProviders } from './shared/providers.browser.js';
|
|
4
4
|
import { browserProviders } from './browser/providers.browser.js';
|
|
5
|
+
import { ChildAppMonitoringTimingModule } from './browser/timing.browser.js';
|
|
5
6
|
export { Assert } from './export.browser.js';
|
|
6
7
|
export { ChildApp } from './shared/react/component.browser.js';
|
|
7
8
|
export * from '@tramvai/tokens-child-app';
|
|
@@ -10,7 +11,7 @@ let ChildAppModule = class ChildAppModule {
|
|
|
10
11
|
};
|
|
11
12
|
ChildAppModule = __decorate([
|
|
12
13
|
Module({
|
|
13
|
-
imports: [],
|
|
14
|
+
imports: process.env.NODE_ENV === 'development' ? [ChildAppMonitoringTimingModule] : [],
|
|
14
15
|
providers: [...sharedProviders, ...browserProviders],
|
|
15
16
|
})
|
|
16
17
|
], ChildAppModule);
|
|
@@ -5,6 +5,10 @@ import { CHILD_APP_INTERNAL_CONFIG_TOKEN, IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKE
|
|
|
5
5
|
|
|
6
6
|
/* eslint-disable no-console */
|
|
7
7
|
class BaseChildAppContractManager {
|
|
8
|
+
appDi;
|
|
9
|
+
hostProvidedContracts;
|
|
10
|
+
hostRequiredContracts;
|
|
11
|
+
log;
|
|
8
12
|
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
9
13
|
this.appDi = appDi;
|
|
10
14
|
this.hostProvidedContracts = hostProvidedContracts ?? [];
|
|
@@ -5,6 +5,10 @@ import { CHILD_APP_INTERNAL_CONFIG_TOKEN, IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKE
|
|
|
5
5
|
|
|
6
6
|
/* eslint-disable no-console */
|
|
7
7
|
class BaseChildAppContractManager {
|
|
8
|
+
appDi;
|
|
9
|
+
hostProvidedContracts;
|
|
10
|
+
hostRequiredContracts;
|
|
11
|
+
log;
|
|
8
12
|
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
9
13
|
this.appDi = appDi;
|
|
10
14
|
this.hostProvidedContracts = hostProvidedContracts ?? [];
|
|
@@ -14,6 +14,10 @@ var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
|
|
|
14
14
|
|
|
15
15
|
/* eslint-disable no-console */
|
|
16
16
|
class BaseChildAppContractManager {
|
|
17
|
+
appDi;
|
|
18
|
+
hostProvidedContracts;
|
|
19
|
+
hostRequiredContracts;
|
|
20
|
+
log;
|
|
17
21
|
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
18
22
|
this.appDi = appDi;
|
|
19
23
|
this.hostProvidedContracts = hostProvidedContracts ?? [];
|
|
@@ -4,6 +4,7 @@ import { CHILD_APP_INTERNAL_CONFIG_TOKEN, CHILD_APP_DI_MANAGER_TOKEN } from '@tr
|
|
|
4
4
|
import { BaseChildAppContractManager } from './contractManager.base.es.js';
|
|
5
5
|
|
|
6
6
|
class ChildAppContractManager extends BaseChildAppContractManager {
|
|
7
|
+
asyncLocalStorage;
|
|
7
8
|
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
8
9
|
super({
|
|
9
10
|
appDi,
|
|
@@ -12,6 +12,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
12
12
|
var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
|
|
13
13
|
|
|
14
14
|
class ChildAppContractManager extends contractManager_base.BaseChildAppContractManager {
|
|
15
|
+
asyncLocalStorage;
|
|
15
16
|
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
16
17
|
super({
|
|
17
18
|
appDi,
|
package/lib/server/loader.d.ts
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
|
-
import type { ChildApp } from '@tramvai/child-app-core';
|
|
2
|
-
import type
|
|
3
|
-
import type { CREATE_CACHE_TOKEN, LOGGER_TOKEN, ENV_MANAGER_TOKEN } from '@tramvai/tokens-common';
|
|
1
|
+
import type { CHILD_APP_LOADER_PLUGIN, ChildApp } from '@tramvai/child-app-core';
|
|
2
|
+
import { CHILD_APP_LOADER_CACHE_OPTIONS_TOKEN, type ChildAppFinalConfig } from '@tramvai/tokens-child-app';
|
|
3
|
+
import type { CREATE_CACHE_TOKEN, LOGGER_TOKEN, ENV_MANAGER_TOKEN, ASYNC_LOCAL_STORAGE_TOKEN } from '@tramvai/tokens-common';
|
|
4
|
+
import { AsyncTapableHookInstance, TAPABLE_HOOK_FACTORY_TOKEN } from '@tramvai/core';
|
|
4
5
|
import { Loader } from '../shared/loader';
|
|
5
6
|
import type { LoadableStats, ModuleFederationStats } from '../shared/webpack/moduleFederation';
|
|
6
7
|
export declare class ServerLoader extends Loader {
|
|
7
8
|
private readonly loader;
|
|
8
9
|
private readonly initializedMap;
|
|
9
|
-
private internalLoadCache;
|
|
10
10
|
private log;
|
|
11
|
-
|
|
11
|
+
private hookFactory;
|
|
12
|
+
loadModuleHook: AsyncTapableHookInstance<{
|
|
13
|
+
config: ChildAppFinalConfig;
|
|
14
|
+
}, ChildApp | undefined>;
|
|
15
|
+
constructor({ logger, createCache, envManager, cacheOptions, asyncLocalStorage, hookFactory, plugins, }: {
|
|
16
|
+
hookFactory: typeof TAPABLE_HOOK_FACTORY_TOKEN;
|
|
12
17
|
logger: typeof LOGGER_TOKEN;
|
|
13
18
|
createCache: typeof CREATE_CACHE_TOKEN;
|
|
14
19
|
envManager: typeof ENV_MANAGER_TOKEN;
|
|
20
|
+
cacheOptions: typeof CHILD_APP_LOADER_CACHE_OPTIONS_TOKEN | null;
|
|
21
|
+
asyncLocalStorage: typeof ASYNC_LOCAL_STORAGE_TOKEN | null;
|
|
22
|
+
plugins: (typeof CHILD_APP_LOADER_PLUGIN)[] | null;
|
|
15
23
|
});
|
|
24
|
+
private loadModule;
|
|
16
25
|
load(config: ChildAppFinalConfig): Promise<ChildApp | void>;
|
|
17
26
|
init(config: ChildAppFinalConfig): Promise<void>;
|
|
18
|
-
get(config: ChildAppFinalConfig): ChildApp |
|
|
27
|
+
get(config: ChildAppFinalConfig): ChildApp | undefined;
|
|
19
28
|
getStats(config: ChildAppFinalConfig): ModuleFederationStats | void;
|
|
20
29
|
getLoadableStats(config: ChildAppFinalConfig): LoadableStats | void;
|
|
21
30
|
waitFor(): Promise<void>;
|