@tramvai/module-child-app 4.22.0 → 4.24.0
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/providers.browser.js +5 -3
- package/lib/browser.js +2 -1
- package/lib/contracts/contractManager.base.browser.js +134 -14
- package/lib/contracts/contractManager.base.d.ts +29 -9
- package/lib/contracts/contractManager.base.es.js +134 -14
- package/lib/contracts/contractManager.base.js +134 -13
- package/lib/contracts/contractManager.browser.browser.js +11 -5
- package/lib/contracts/contractManager.browser.d.ts +4 -9
- package/lib/contracts/contractManager.server.d.ts +8 -5
- package/lib/contracts/contractManager.server.es.js +21 -4
- package/lib/contracts/contractManager.server.js +21 -4
- package/lib/export.browser.js +11 -0
- package/lib/export.d.ts +51 -0
- package/lib/export.es.js +11 -0
- package/lib/export.js +22 -0
- package/lib/server/providers.es.js +4 -2
- package/lib/server/providers.js +3 -1
- package/lib/server.es.js +2 -1
- package/lib/server.js +3 -1
- package/lib/shared/singletonDi.browser.js +1 -0
- package/lib/shared/singletonDi.es.js +1 -0
- package/lib/shared/singletonDi.js +1 -0
- package/package.json +12 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Scope, DI_TOKEN } from '@tinkoff/dippy';
|
|
1
|
+
import { Scope, DI_TOKEN, optional } from '@tinkoff/dippy';
|
|
2
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 } from '@tramvai/tokens-child-app';
|
|
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';
|
|
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';
|
|
@@ -136,7 +136,9 @@ const browserProviders = [
|
|
|
136
136
|
useFactory: (deps) => new ChildAppContractManager(deps),
|
|
137
137
|
deps: {
|
|
138
138
|
appDi: DI_TOKEN,
|
|
139
|
-
hostProvidedContracts: HOST_PROVIDED_CONTRACTS,
|
|
139
|
+
hostProvidedContracts: optional(HOST_PROVIDED_CONTRACTS),
|
|
140
|
+
hostRequiredContracts: optional(HOST_REQUIRED_CONTRACTS),
|
|
141
|
+
logger: LOGGER_TOKEN,
|
|
140
142
|
},
|
|
141
143
|
}),
|
|
142
144
|
provide({
|
package/lib/browser.js
CHANGED
|
@@ -2,8 +2,9 @@ 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
|
-
export
|
|
5
|
+
export { Assert } from './export.browser.js';
|
|
6
6
|
export { ChildApp } from './shared/react/component.browser.js';
|
|
7
|
+
export * from '@tramvai/tokens-child-app';
|
|
7
8
|
|
|
8
9
|
let ChildAppModule = class ChildAppModule {
|
|
9
10
|
};
|
|
@@ -1,33 +1,140 @@
|
|
|
1
1
|
import flatten from '@tinkoff/utils/array/flatten';
|
|
2
|
+
import isNil from '@tinkoff/utils/is/nil';
|
|
2
3
|
import { optional } from '@tinkoff/dippy';
|
|
3
|
-
import { CHILD_APP_INTERNAL_CONFIG_TOKEN, IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN, CHILD_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
4
|
+
import { CHILD_APP_INTERNAL_CONFIG_TOKEN, IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN, CHILD_REQUIRED_CONTRACTS, CHILD_CONTRACTS_FALLBACK, HOST_CONTRACTS_FALLBACK, CHILD_APP_PRELOAD_MANAGER_TOKEN, CHILD_APP_RESOLVE_CONFIG_TOKEN, CHILD_PROVIDED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
4
5
|
|
|
6
|
+
/* eslint-disable no-console */
|
|
5
7
|
class BaseChildAppContractManager {
|
|
6
|
-
constructor({ hostProvidedContracts }) {
|
|
7
|
-
this.
|
|
8
|
+
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
9
|
+
this.appDi = appDi;
|
|
10
|
+
this.hostProvidedContracts = hostProvidedContracts !== null && hostProvidedContracts !== void 0 ? hostProvidedContracts : [];
|
|
11
|
+
this.hostRequiredContracts = hostRequiredContracts !== null && hostRequiredContracts !== void 0 ? hostRequiredContracts : [];
|
|
12
|
+
this.log = logger('child-app:contract-manager');
|
|
8
13
|
}
|
|
9
14
|
registerChildContracts(childDi) {
|
|
10
|
-
var _a;
|
|
15
|
+
var _a, _b;
|
|
11
16
|
const childAppConfig = childDi.get(CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
12
17
|
const childHasContractsSupport = childDi.get(optional(IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN));
|
|
13
18
|
const childRequiredContracts = flatten((_a = childDi.get(optional(CHILD_REQUIRED_CONTRACTS))) !== null && _a !== void 0 ? _a : []);
|
|
14
|
-
const childRequiredContractsKeys = childRequiredContracts.map((c) => c.toString());
|
|
15
19
|
const hostProvidedContracts = this.getHostProvidedContracts(childAppConfig.name);
|
|
20
|
+
const hostProvidedContractsKeys = hostProvidedContracts.map((c) => c.toString());
|
|
16
21
|
// if contracts unsupported, it is a legacy child app, and we need to register all possible contracts
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
if (!childHasContractsSupport) {
|
|
23
|
+
hostProvidedContracts.forEach((contract) => {
|
|
24
|
+
this.registerContract(childDi, contract);
|
|
25
|
+
});
|
|
26
|
+
// otherwise register only required for child app contracts
|
|
27
|
+
}
|
|
28
|
+
else if (childHasContractsSupport && childRequiredContracts.length > 0) {
|
|
29
|
+
const missedContracts = [];
|
|
30
|
+
childRequiredContracts.forEach((contract) => {
|
|
21
31
|
const contractKey = contract.toString();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
if (hostProvidedContractsKeys.includes(contractKey)) {
|
|
33
|
+
this.registerContract(childDi,
|
|
34
|
+
// we can't use `contract` here, because token from Child App chunk and from host bundle will not be equal by reference
|
|
35
|
+
hostProvidedContracts.find((c) => c.toString() === contractKey));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this.log.warn(`Contract "${contract}" for "${childAppConfig.name}" Child App is not provided in the application`);
|
|
39
|
+
missedContracts.push(contract);
|
|
27
40
|
}
|
|
41
|
+
});
|
|
42
|
+
if (missedContracts.length) {
|
|
43
|
+
this.log.warn({
|
|
44
|
+
message: `Missed contracts for "${childAppConfig.name}" Child App`,
|
|
45
|
+
missedContracts,
|
|
46
|
+
});
|
|
47
|
+
const fallbacks = (_b = childDi.get(optional(CHILD_CONTRACTS_FALLBACK))) !== null && _b !== void 0 ? _b : [];
|
|
48
|
+
fallbacks.forEach((fallback) => {
|
|
49
|
+
fallback({
|
|
50
|
+
childDi,
|
|
51
|
+
missedContracts,
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
validateChildProvidedContracts(childDi) {
|
|
58
|
+
var _a;
|
|
59
|
+
const childAppConfig = childDi.get(CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
60
|
+
const hostDi = this.getRequestHostDi();
|
|
61
|
+
const childProvidedContracts = this.getChildProvidedContracts(childDi);
|
|
62
|
+
const childProvidedContractsKeys = childProvidedContracts.map((c) => c.toString());
|
|
63
|
+
const hostRequiredContracts = this.getHostRequiredContracts(childAppConfig.name);
|
|
64
|
+
const missedContracts = [];
|
|
65
|
+
hostRequiredContracts.forEach((required) => {
|
|
66
|
+
const requiredKey = required.toString();
|
|
67
|
+
if (!childProvidedContractsKeys.includes(requiredKey)) {
|
|
68
|
+
missedContracts.push(required);
|
|
28
69
|
}
|
|
70
|
+
});
|
|
71
|
+
if (missedContracts.length) {
|
|
72
|
+
this.log.warn({
|
|
73
|
+
message: `Missed contracts for application, required from "${childAppConfig.name}" Child App`,
|
|
74
|
+
missedContracts,
|
|
75
|
+
});
|
|
76
|
+
const fallbacks = (_a = hostDi.get(optional(HOST_CONTRACTS_FALLBACK))) !== null && _a !== void 0 ? _a : [];
|
|
77
|
+
fallbacks.forEach((fallback) => {
|
|
78
|
+
fallback({
|
|
79
|
+
hostDi,
|
|
80
|
+
missedContracts,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
29
83
|
}
|
|
30
84
|
}
|
|
85
|
+
async getChildProvidedContract(childAppName, contract) {
|
|
86
|
+
var _a, _b, _c, _d;
|
|
87
|
+
try {
|
|
88
|
+
// Resolve CHILD_APP_PRELOAD_MANAGER_TOKEN from DI to prevent circular dependency error
|
|
89
|
+
const childAppPreloadManager = this.appDi.get(CHILD_APP_PRELOAD_MANAGER_TOKEN);
|
|
90
|
+
// Wait for Child App loading before trying to resolve contract from Child App DI
|
|
91
|
+
await childAppPreloadManager.preload({ name: childAppName });
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const childAppDi = this.getChildDi(childAppName);
|
|
97
|
+
const childProvidedContracts = this.getChildProvidedContracts(childAppName);
|
|
98
|
+
const childProvidedContractsKeys = childProvidedContracts.map((c) => c.toString());
|
|
99
|
+
const hostRequiredContracts = this.getHostRequiredContracts(childAppName);
|
|
100
|
+
const hostRequiredContractsKeys = hostRequiredContracts.map((c) => c.toString());
|
|
101
|
+
if (!hostRequiredContractsKeys.includes(contract.toString())) {
|
|
102
|
+
this.log.warn(`Contract "${contract}" is not required in the application`);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
if (!childProvidedContractsKeys.includes(contract.toString())) {
|
|
106
|
+
this.log.warn(`Contract "${contract}" is not provided in the "${childAppName}" Child App`);
|
|
107
|
+
}
|
|
108
|
+
const result = ((_d = (_c = (_a = childAppDi === null || childAppDi === void 0 ? void 0 : childAppDi.get(optional(contract))) !== null && _a !== void 0 ? _a :
|
|
109
|
+
// contract can be registered in host DI in fallback
|
|
110
|
+
(_b = this.getRequestHostDi()) === null || _b === void 0 ? void 0 : _b.get(optional(contract))) !== null && _c !== void 0 ? _c : this.appDi.get(optional(contract))) !== null && _d !== void 0 ? _d : null);
|
|
111
|
+
if (isNil(result)) {
|
|
112
|
+
this.log.warn(`Contract "${contract}" is declared but not provided in the "${childAppName}" Child App or application contracts fallback`);
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
getChildDi(childAppName) {
|
|
117
|
+
var _a;
|
|
118
|
+
// Resolve CHILD_APP_RESOLVE_CONFIG_TOKEN from DI to prevent scope conflict warning
|
|
119
|
+
const resolveChildAppConfig = ((_a = this.getRequestHostDi()) !== null && _a !== void 0 ? _a : this.appDi).get(CHILD_APP_RESOLVE_CONFIG_TOKEN);
|
|
120
|
+
const childAppConfig = resolveChildAppConfig({ name: childAppName });
|
|
121
|
+
// ContractManager has Singleton scope, and we need to get Request scope Child App DI container.
|
|
122
|
+
// At server-side it will be resolved from Async Local Storage, at client-side everything is Singleton
|
|
123
|
+
const childAppDiManager = this.getRequestChildDiManager();
|
|
124
|
+
const childAppDi = childAppDiManager === null || childAppDiManager === void 0 ? void 0 : childAppDiManager.getChildDi(childAppConfig);
|
|
125
|
+
return childAppDi;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Pass DI here when we can't resolve it from Child DI manager without cycle
|
|
129
|
+
* - `Container` is used in case when `validateChildProvidedContracts` call this method
|
|
130
|
+
* - `string` is used in case when `getChildProvidedContract` call this method
|
|
131
|
+
*/
|
|
132
|
+
getChildProvidedContracts(childAppNameOrDi) {
|
|
133
|
+
var _a;
|
|
134
|
+
const childAppDi = typeof childAppNameOrDi === 'string' ? this.getChildDi(childAppNameOrDi) : childAppNameOrDi;
|
|
135
|
+
const childProvidedContracts = flatten((_a = childAppDi === null || childAppDi === void 0 ? void 0 : childAppDi.get(optional(CHILD_PROVIDED_CONTRACTS))) !== null && _a !== void 0 ? _a : []);
|
|
136
|
+
return childProvidedContracts;
|
|
137
|
+
}
|
|
31
138
|
getHostProvidedContracts(childAppName) {
|
|
32
139
|
const contracts = [];
|
|
33
140
|
// look over all provided by host contracts
|
|
@@ -41,6 +148,19 @@ class BaseChildAppContractManager {
|
|
|
41
148
|
}
|
|
42
149
|
return contracts;
|
|
43
150
|
}
|
|
151
|
+
getHostRequiredContracts(childAppName) {
|
|
152
|
+
const contracts = [];
|
|
153
|
+
// look over all required by host contracts
|
|
154
|
+
for (const contract of this.hostRequiredContracts) {
|
|
155
|
+
// host require contract from specific Child APp
|
|
156
|
+
const contractFromChild = contract.childAppName === childAppName;
|
|
157
|
+
if (contractFromChild) {
|
|
158
|
+
contracts.push(...contract.requiredContracts);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return contracts;
|
|
162
|
+
}
|
|
44
163
|
}
|
|
164
|
+
/* eslint-enable no-console */
|
|
45
165
|
|
|
46
166
|
export { BaseChildAppContractManager };
|
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
import type { ExtractDependencyType } from '@tinkoff/dippy';
|
|
1
|
+
import type { ExtractDependencyType, TokenInterface } from '@tinkoff/dippy';
|
|
2
2
|
import { type Container } from '@tinkoff/dippy';
|
|
3
|
-
import type { Contract, HOST_PROVIDED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
4
|
-
import
|
|
5
|
-
type HostProvidedContracts = ExtractDependencyType<typeof HOST_PROVIDED_CONTRACTS>;
|
|
3
|
+
import type { CHILD_APP_DI_MANAGER_TOKEN, Contract, HOST_PROVIDED_CONTRACTS, HOST_REQUIRED_CONTRACTS, ChildAppContractManager as IChildAppContractManager } from '@tramvai/tokens-child-app';
|
|
4
|
+
import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
5
|
+
export type HostProvidedContracts = ExtractDependencyType<typeof HOST_PROVIDED_CONTRACTS>;
|
|
6
|
+
export type HostRequiredContracts = ExtractDependencyType<typeof HOST_REQUIRED_CONTRACTS>;
|
|
7
|
+
export type ChildAppDiManager = ExtractDependencyType<typeof CHILD_APP_DI_MANAGER_TOKEN>;
|
|
8
|
+
export type Logger = ExtractDependencyType<typeof LOGGER_TOKEN>;
|
|
6
9
|
export declare abstract class BaseChildAppContractManager implements IChildAppContractManager {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
protected appDi: Container;
|
|
11
|
+
protected hostProvidedContracts: HostProvidedContracts;
|
|
12
|
+
protected hostRequiredContracts: HostRequiredContracts;
|
|
13
|
+
protected log: ReturnType<Logger>;
|
|
14
|
+
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }: {
|
|
15
|
+
appDi: Container;
|
|
16
|
+
hostProvidedContracts: HostProvidedContracts | null;
|
|
17
|
+
hostRequiredContracts: HostRequiredContracts | null;
|
|
18
|
+
logger: Logger;
|
|
10
19
|
});
|
|
20
|
+
protected abstract registerContract(childDi: Container, contract: Contract): void;
|
|
21
|
+
protected abstract getRequestHostDi(): Container | null;
|
|
22
|
+
protected abstract getRequestChildDiManager(): ChildAppDiManager | null;
|
|
11
23
|
registerChildContracts(childDi: Container): void;
|
|
12
|
-
|
|
24
|
+
validateChildProvidedContracts(childDi: Container): void;
|
|
25
|
+
getChildProvidedContract<T extends TokenInterface<any>>(childAppName: string, contract: T): Promise<ExtractDependencyType<T> | null>;
|
|
26
|
+
private getChildDi;
|
|
27
|
+
/**
|
|
28
|
+
* Pass DI here when we can't resolve it from Child DI manager without cycle
|
|
29
|
+
* - `Container` is used in case when `validateChildProvidedContracts` call this method
|
|
30
|
+
* - `string` is used in case when `getChildProvidedContract` call this method
|
|
31
|
+
*/
|
|
32
|
+
private getChildProvidedContracts;
|
|
13
33
|
private getHostProvidedContracts;
|
|
34
|
+
private getHostRequiredContracts;
|
|
14
35
|
}
|
|
15
|
-
export {};
|
|
16
36
|
//# sourceMappingURL=contractManager.base.d.ts.map
|
|
@@ -1,33 +1,140 @@
|
|
|
1
1
|
import flatten from '@tinkoff/utils/array/flatten';
|
|
2
|
+
import isNil from '@tinkoff/utils/is/nil';
|
|
2
3
|
import { optional } from '@tinkoff/dippy';
|
|
3
|
-
import { CHILD_APP_INTERNAL_CONFIG_TOKEN, IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN, CHILD_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
4
|
+
import { CHILD_APP_INTERNAL_CONFIG_TOKEN, IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN, CHILD_REQUIRED_CONTRACTS, CHILD_CONTRACTS_FALLBACK, HOST_CONTRACTS_FALLBACK, CHILD_APP_PRELOAD_MANAGER_TOKEN, CHILD_APP_RESOLVE_CONFIG_TOKEN, CHILD_PROVIDED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
4
5
|
|
|
6
|
+
/* eslint-disable no-console */
|
|
5
7
|
class BaseChildAppContractManager {
|
|
6
|
-
constructor({ hostProvidedContracts }) {
|
|
7
|
-
this.
|
|
8
|
+
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
9
|
+
this.appDi = appDi;
|
|
10
|
+
this.hostProvidedContracts = hostProvidedContracts !== null && hostProvidedContracts !== void 0 ? hostProvidedContracts : [];
|
|
11
|
+
this.hostRequiredContracts = hostRequiredContracts !== null && hostRequiredContracts !== void 0 ? hostRequiredContracts : [];
|
|
12
|
+
this.log = logger('child-app:contract-manager');
|
|
8
13
|
}
|
|
9
14
|
registerChildContracts(childDi) {
|
|
10
|
-
var _a;
|
|
15
|
+
var _a, _b;
|
|
11
16
|
const childAppConfig = childDi.get(CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
12
17
|
const childHasContractsSupport = childDi.get(optional(IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN));
|
|
13
18
|
const childRequiredContracts = flatten((_a = childDi.get(optional(CHILD_REQUIRED_CONTRACTS))) !== null && _a !== void 0 ? _a : []);
|
|
14
|
-
const childRequiredContractsKeys = childRequiredContracts.map((c) => c.toString());
|
|
15
19
|
const hostProvidedContracts = this.getHostProvidedContracts(childAppConfig.name);
|
|
20
|
+
const hostProvidedContractsKeys = hostProvidedContracts.map((c) => c.toString());
|
|
16
21
|
// if contracts unsupported, it is a legacy child app, and we need to register all possible contracts
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
if (!childHasContractsSupport) {
|
|
23
|
+
hostProvidedContracts.forEach((contract) => {
|
|
24
|
+
this.registerContract(childDi, contract);
|
|
25
|
+
});
|
|
26
|
+
// otherwise register only required for child app contracts
|
|
27
|
+
}
|
|
28
|
+
else if (childHasContractsSupport && childRequiredContracts.length > 0) {
|
|
29
|
+
const missedContracts = [];
|
|
30
|
+
childRequiredContracts.forEach((contract) => {
|
|
21
31
|
const contractKey = contract.toString();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
if (hostProvidedContractsKeys.includes(contractKey)) {
|
|
33
|
+
this.registerContract(childDi,
|
|
34
|
+
// we can't use `contract` here, because token from Child App chunk and from host bundle will not be equal by reference
|
|
35
|
+
hostProvidedContracts.find((c) => c.toString() === contractKey));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this.log.warn(`Contract "${contract}" for "${childAppConfig.name}" Child App is not provided in the application`);
|
|
39
|
+
missedContracts.push(contract);
|
|
27
40
|
}
|
|
41
|
+
});
|
|
42
|
+
if (missedContracts.length) {
|
|
43
|
+
this.log.warn({
|
|
44
|
+
message: `Missed contracts for "${childAppConfig.name}" Child App`,
|
|
45
|
+
missedContracts,
|
|
46
|
+
});
|
|
47
|
+
const fallbacks = (_b = childDi.get(optional(CHILD_CONTRACTS_FALLBACK))) !== null && _b !== void 0 ? _b : [];
|
|
48
|
+
fallbacks.forEach((fallback) => {
|
|
49
|
+
fallback({
|
|
50
|
+
childDi,
|
|
51
|
+
missedContracts,
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
validateChildProvidedContracts(childDi) {
|
|
58
|
+
var _a;
|
|
59
|
+
const childAppConfig = childDi.get(CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
60
|
+
const hostDi = this.getRequestHostDi();
|
|
61
|
+
const childProvidedContracts = this.getChildProvidedContracts(childDi);
|
|
62
|
+
const childProvidedContractsKeys = childProvidedContracts.map((c) => c.toString());
|
|
63
|
+
const hostRequiredContracts = this.getHostRequiredContracts(childAppConfig.name);
|
|
64
|
+
const missedContracts = [];
|
|
65
|
+
hostRequiredContracts.forEach((required) => {
|
|
66
|
+
const requiredKey = required.toString();
|
|
67
|
+
if (!childProvidedContractsKeys.includes(requiredKey)) {
|
|
68
|
+
missedContracts.push(required);
|
|
28
69
|
}
|
|
70
|
+
});
|
|
71
|
+
if (missedContracts.length) {
|
|
72
|
+
this.log.warn({
|
|
73
|
+
message: `Missed contracts for application, required from "${childAppConfig.name}" Child App`,
|
|
74
|
+
missedContracts,
|
|
75
|
+
});
|
|
76
|
+
const fallbacks = (_a = hostDi.get(optional(HOST_CONTRACTS_FALLBACK))) !== null && _a !== void 0 ? _a : [];
|
|
77
|
+
fallbacks.forEach((fallback) => {
|
|
78
|
+
fallback({
|
|
79
|
+
hostDi,
|
|
80
|
+
missedContracts,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
29
83
|
}
|
|
30
84
|
}
|
|
85
|
+
async getChildProvidedContract(childAppName, contract) {
|
|
86
|
+
var _a, _b, _c, _d;
|
|
87
|
+
try {
|
|
88
|
+
// Resolve CHILD_APP_PRELOAD_MANAGER_TOKEN from DI to prevent circular dependency error
|
|
89
|
+
const childAppPreloadManager = this.appDi.get(CHILD_APP_PRELOAD_MANAGER_TOKEN);
|
|
90
|
+
// Wait for Child App loading before trying to resolve contract from Child App DI
|
|
91
|
+
await childAppPreloadManager.preload({ name: childAppName });
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const childAppDi = this.getChildDi(childAppName);
|
|
97
|
+
const childProvidedContracts = this.getChildProvidedContracts(childAppName);
|
|
98
|
+
const childProvidedContractsKeys = childProvidedContracts.map((c) => c.toString());
|
|
99
|
+
const hostRequiredContracts = this.getHostRequiredContracts(childAppName);
|
|
100
|
+
const hostRequiredContractsKeys = hostRequiredContracts.map((c) => c.toString());
|
|
101
|
+
if (!hostRequiredContractsKeys.includes(contract.toString())) {
|
|
102
|
+
this.log.warn(`Contract "${contract}" is not required in the application`);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
if (!childProvidedContractsKeys.includes(contract.toString())) {
|
|
106
|
+
this.log.warn(`Contract "${contract}" is not provided in the "${childAppName}" Child App`);
|
|
107
|
+
}
|
|
108
|
+
const result = ((_d = (_c = (_a = childAppDi === null || childAppDi === void 0 ? void 0 : childAppDi.get(optional(contract))) !== null && _a !== void 0 ? _a :
|
|
109
|
+
// contract can be registered in host DI in fallback
|
|
110
|
+
(_b = this.getRequestHostDi()) === null || _b === void 0 ? void 0 : _b.get(optional(contract))) !== null && _c !== void 0 ? _c : this.appDi.get(optional(contract))) !== null && _d !== void 0 ? _d : null);
|
|
111
|
+
if (isNil(result)) {
|
|
112
|
+
this.log.warn(`Contract "${contract}" is declared but not provided in the "${childAppName}" Child App or application contracts fallback`);
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
getChildDi(childAppName) {
|
|
117
|
+
var _a;
|
|
118
|
+
// Resolve CHILD_APP_RESOLVE_CONFIG_TOKEN from DI to prevent scope conflict warning
|
|
119
|
+
const resolveChildAppConfig = ((_a = this.getRequestHostDi()) !== null && _a !== void 0 ? _a : this.appDi).get(CHILD_APP_RESOLVE_CONFIG_TOKEN);
|
|
120
|
+
const childAppConfig = resolveChildAppConfig({ name: childAppName });
|
|
121
|
+
// ContractManager has Singleton scope, and we need to get Request scope Child App DI container.
|
|
122
|
+
// At server-side it will be resolved from Async Local Storage, at client-side everything is Singleton
|
|
123
|
+
const childAppDiManager = this.getRequestChildDiManager();
|
|
124
|
+
const childAppDi = childAppDiManager === null || childAppDiManager === void 0 ? void 0 : childAppDiManager.getChildDi(childAppConfig);
|
|
125
|
+
return childAppDi;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Pass DI here when we can't resolve it from Child DI manager without cycle
|
|
129
|
+
* - `Container` is used in case when `validateChildProvidedContracts` call this method
|
|
130
|
+
* - `string` is used in case when `getChildProvidedContract` call this method
|
|
131
|
+
*/
|
|
132
|
+
getChildProvidedContracts(childAppNameOrDi) {
|
|
133
|
+
var _a;
|
|
134
|
+
const childAppDi = typeof childAppNameOrDi === 'string' ? this.getChildDi(childAppNameOrDi) : childAppNameOrDi;
|
|
135
|
+
const childProvidedContracts = flatten((_a = childAppDi === null || childAppDi === void 0 ? void 0 : childAppDi.get(optional(CHILD_PROVIDED_CONTRACTS))) !== null && _a !== void 0 ? _a : []);
|
|
136
|
+
return childProvidedContracts;
|
|
137
|
+
}
|
|
31
138
|
getHostProvidedContracts(childAppName) {
|
|
32
139
|
const contracts = [];
|
|
33
140
|
// look over all provided by host contracts
|
|
@@ -41,6 +148,19 @@ class BaseChildAppContractManager {
|
|
|
41
148
|
}
|
|
42
149
|
return contracts;
|
|
43
150
|
}
|
|
151
|
+
getHostRequiredContracts(childAppName) {
|
|
152
|
+
const contracts = [];
|
|
153
|
+
// look over all required by host contracts
|
|
154
|
+
for (const contract of this.hostRequiredContracts) {
|
|
155
|
+
// host require contract from specific Child APp
|
|
156
|
+
const contractFromChild = contract.childAppName === childAppName;
|
|
157
|
+
if (contractFromChild) {
|
|
158
|
+
contracts.push(...contract.requiredContracts);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return contracts;
|
|
162
|
+
}
|
|
44
163
|
}
|
|
164
|
+
/* eslint-enable no-console */
|
|
45
165
|
|
|
46
166
|
export { BaseChildAppContractManager };
|
|
@@ -3,39 +3,147 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var flatten = require('@tinkoff/utils/array/flatten');
|
|
6
|
+
var isNil = require('@tinkoff/utils/is/nil');
|
|
6
7
|
var dippy = require('@tinkoff/dippy');
|
|
7
8
|
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
8
9
|
|
|
9
10
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
11
|
|
|
11
12
|
var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
|
|
13
|
+
var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
|
|
12
14
|
|
|
15
|
+
/* eslint-disable no-console */
|
|
13
16
|
class BaseChildAppContractManager {
|
|
14
|
-
constructor({ hostProvidedContracts }) {
|
|
15
|
-
this.
|
|
17
|
+
constructor({ appDi, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
18
|
+
this.appDi = appDi;
|
|
19
|
+
this.hostProvidedContracts = hostProvidedContracts !== null && hostProvidedContracts !== void 0 ? hostProvidedContracts : [];
|
|
20
|
+
this.hostRequiredContracts = hostRequiredContracts !== null && hostRequiredContracts !== void 0 ? hostRequiredContracts : [];
|
|
21
|
+
this.log = logger('child-app:contract-manager');
|
|
16
22
|
}
|
|
17
23
|
registerChildContracts(childDi) {
|
|
18
|
-
var _a;
|
|
24
|
+
var _a, _b;
|
|
19
25
|
const childAppConfig = childDi.get(tokensChildApp.CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
20
26
|
const childHasContractsSupport = childDi.get(dippy.optional(tokensChildApp.IS_CHILD_APP_CONTRACTS_COMPATIBLE_TOKEN));
|
|
21
27
|
const childRequiredContracts = flatten__default["default"]((_a = childDi.get(dippy.optional(tokensChildApp.CHILD_REQUIRED_CONTRACTS))) !== null && _a !== void 0 ? _a : []);
|
|
22
|
-
const childRequiredContractsKeys = childRequiredContracts.map((c) => c.toString());
|
|
23
28
|
const hostProvidedContracts = this.getHostProvidedContracts(childAppConfig.name);
|
|
29
|
+
const hostProvidedContractsKeys = hostProvidedContracts.map((c) => c.toString());
|
|
24
30
|
// if contracts unsupported, it is a legacy child app, and we need to register all possible contracts
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
if (!childHasContractsSupport) {
|
|
32
|
+
hostProvidedContracts.forEach((contract) => {
|
|
33
|
+
this.registerContract(childDi, contract);
|
|
34
|
+
});
|
|
35
|
+
// otherwise register only required for child app contracts
|
|
36
|
+
}
|
|
37
|
+
else if (childHasContractsSupport && childRequiredContracts.length > 0) {
|
|
38
|
+
const missedContracts = [];
|
|
39
|
+
childRequiredContracts.forEach((contract) => {
|
|
29
40
|
const contractKey = contract.toString();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
if (hostProvidedContractsKeys.includes(contractKey)) {
|
|
42
|
+
this.registerContract(childDi,
|
|
43
|
+
// we can't use `contract` here, because token from Child App chunk and from host bundle will not be equal by reference
|
|
44
|
+
hostProvidedContracts.find((c) => c.toString() === contractKey));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.log.warn(`Contract "${contract}" for "${childAppConfig.name}" Child App is not provided in the application`);
|
|
48
|
+
missedContracts.push(contract);
|
|
35
49
|
}
|
|
50
|
+
});
|
|
51
|
+
if (missedContracts.length) {
|
|
52
|
+
this.log.warn({
|
|
53
|
+
message: `Missed contracts for "${childAppConfig.name}" Child App`,
|
|
54
|
+
missedContracts,
|
|
55
|
+
});
|
|
56
|
+
const fallbacks = (_b = childDi.get(dippy.optional(tokensChildApp.CHILD_CONTRACTS_FALLBACK))) !== null && _b !== void 0 ? _b : [];
|
|
57
|
+
fallbacks.forEach((fallback) => {
|
|
58
|
+
fallback({
|
|
59
|
+
childDi,
|
|
60
|
+
missedContracts,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
validateChildProvidedContracts(childDi) {
|
|
67
|
+
var _a;
|
|
68
|
+
const childAppConfig = childDi.get(tokensChildApp.CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
69
|
+
const hostDi = this.getRequestHostDi();
|
|
70
|
+
const childProvidedContracts = this.getChildProvidedContracts(childDi);
|
|
71
|
+
const childProvidedContractsKeys = childProvidedContracts.map((c) => c.toString());
|
|
72
|
+
const hostRequiredContracts = this.getHostRequiredContracts(childAppConfig.name);
|
|
73
|
+
const missedContracts = [];
|
|
74
|
+
hostRequiredContracts.forEach((required) => {
|
|
75
|
+
const requiredKey = required.toString();
|
|
76
|
+
if (!childProvidedContractsKeys.includes(requiredKey)) {
|
|
77
|
+
missedContracts.push(required);
|
|
36
78
|
}
|
|
79
|
+
});
|
|
80
|
+
if (missedContracts.length) {
|
|
81
|
+
this.log.warn({
|
|
82
|
+
message: `Missed contracts for application, required from "${childAppConfig.name}" Child App`,
|
|
83
|
+
missedContracts,
|
|
84
|
+
});
|
|
85
|
+
const fallbacks = (_a = hostDi.get(dippy.optional(tokensChildApp.HOST_CONTRACTS_FALLBACK))) !== null && _a !== void 0 ? _a : [];
|
|
86
|
+
fallbacks.forEach((fallback) => {
|
|
87
|
+
fallback({
|
|
88
|
+
hostDi,
|
|
89
|
+
missedContracts,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
37
92
|
}
|
|
38
93
|
}
|
|
94
|
+
async getChildProvidedContract(childAppName, contract) {
|
|
95
|
+
var _a, _b, _c, _d;
|
|
96
|
+
try {
|
|
97
|
+
// Resolve CHILD_APP_PRELOAD_MANAGER_TOKEN from DI to prevent circular dependency error
|
|
98
|
+
const childAppPreloadManager = this.appDi.get(tokensChildApp.CHILD_APP_PRELOAD_MANAGER_TOKEN);
|
|
99
|
+
// Wait for Child App loading before trying to resolve contract from Child App DI
|
|
100
|
+
await childAppPreloadManager.preload({ name: childAppName });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const childAppDi = this.getChildDi(childAppName);
|
|
106
|
+
const childProvidedContracts = this.getChildProvidedContracts(childAppName);
|
|
107
|
+
const childProvidedContractsKeys = childProvidedContracts.map((c) => c.toString());
|
|
108
|
+
const hostRequiredContracts = this.getHostRequiredContracts(childAppName);
|
|
109
|
+
const hostRequiredContractsKeys = hostRequiredContracts.map((c) => c.toString());
|
|
110
|
+
if (!hostRequiredContractsKeys.includes(contract.toString())) {
|
|
111
|
+
this.log.warn(`Contract "${contract}" is not required in the application`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
if (!childProvidedContractsKeys.includes(contract.toString())) {
|
|
115
|
+
this.log.warn(`Contract "${contract}" is not provided in the "${childAppName}" Child App`);
|
|
116
|
+
}
|
|
117
|
+
const result = ((_d = (_c = (_a = childAppDi === null || childAppDi === void 0 ? void 0 : childAppDi.get(dippy.optional(contract))) !== null && _a !== void 0 ? _a :
|
|
118
|
+
// contract can be registered in host DI in fallback
|
|
119
|
+
(_b = this.getRequestHostDi()) === null || _b === void 0 ? void 0 : _b.get(dippy.optional(contract))) !== null && _c !== void 0 ? _c : this.appDi.get(dippy.optional(contract))) !== null && _d !== void 0 ? _d : null);
|
|
120
|
+
if (isNil__default["default"](result)) {
|
|
121
|
+
this.log.warn(`Contract "${contract}" is declared but not provided in the "${childAppName}" Child App or application contracts fallback`);
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
getChildDi(childAppName) {
|
|
126
|
+
var _a;
|
|
127
|
+
// Resolve CHILD_APP_RESOLVE_CONFIG_TOKEN from DI to prevent scope conflict warning
|
|
128
|
+
const resolveChildAppConfig = ((_a = this.getRequestHostDi()) !== null && _a !== void 0 ? _a : this.appDi).get(tokensChildApp.CHILD_APP_RESOLVE_CONFIG_TOKEN);
|
|
129
|
+
const childAppConfig = resolveChildAppConfig({ name: childAppName });
|
|
130
|
+
// ContractManager has Singleton scope, and we need to get Request scope Child App DI container.
|
|
131
|
+
// At server-side it will be resolved from Async Local Storage, at client-side everything is Singleton
|
|
132
|
+
const childAppDiManager = this.getRequestChildDiManager();
|
|
133
|
+
const childAppDi = childAppDiManager === null || childAppDiManager === void 0 ? void 0 : childAppDiManager.getChildDi(childAppConfig);
|
|
134
|
+
return childAppDi;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Pass DI here when we can't resolve it from Child DI manager without cycle
|
|
138
|
+
* - `Container` is used in case when `validateChildProvidedContracts` call this method
|
|
139
|
+
* - `string` is used in case when `getChildProvidedContract` call this method
|
|
140
|
+
*/
|
|
141
|
+
getChildProvidedContracts(childAppNameOrDi) {
|
|
142
|
+
var _a;
|
|
143
|
+
const childAppDi = typeof childAppNameOrDi === 'string' ? this.getChildDi(childAppNameOrDi) : childAppNameOrDi;
|
|
144
|
+
const childProvidedContracts = flatten__default["default"]((_a = childAppDi === null || childAppDi === void 0 ? void 0 : childAppDi.get(dippy.optional(tokensChildApp.CHILD_PROVIDED_CONTRACTS))) !== null && _a !== void 0 ? _a : []);
|
|
145
|
+
return childProvidedContracts;
|
|
146
|
+
}
|
|
39
147
|
getHostProvidedContracts(childAppName) {
|
|
40
148
|
const contracts = [];
|
|
41
149
|
// look over all provided by host contracts
|
|
@@ -49,6 +157,19 @@ class BaseChildAppContractManager {
|
|
|
49
157
|
}
|
|
50
158
|
return contracts;
|
|
51
159
|
}
|
|
160
|
+
getHostRequiredContracts(childAppName) {
|
|
161
|
+
const contracts = [];
|
|
162
|
+
// look over all required by host contracts
|
|
163
|
+
for (const contract of this.hostRequiredContracts) {
|
|
164
|
+
// host require contract from specific Child APp
|
|
165
|
+
const contractFromChild = contract.childAppName === childAppName;
|
|
166
|
+
if (contractFromChild) {
|
|
167
|
+
contracts.push(...contract.requiredContracts);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return contracts;
|
|
171
|
+
}
|
|
52
172
|
}
|
|
173
|
+
/* eslint-enable no-console */
|
|
53
174
|
|
|
54
175
|
exports.BaseChildAppContractManager = BaseChildAppContractManager;
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
import isNil from '@tinkoff/utils/is/nil';
|
|
2
2
|
import { provide, optional } from '@tinkoff/dippy';
|
|
3
|
+
import { CHILD_APP_INTERNAL_CONFIG_TOKEN, CHILD_APP_DI_MANAGER_TOKEN } from '@tramvai/tokens-child-app';
|
|
3
4
|
import { BaseChildAppContractManager } from './contractManager.base.browser.js';
|
|
4
5
|
|
|
5
6
|
class ChildAppContractManager extends BaseChildAppContractManager {
|
|
6
|
-
constructor({ appDi, hostProvidedContracts, }) {
|
|
7
|
-
super({ hostProvidedContracts });
|
|
8
|
-
this.appDi = appDi;
|
|
9
|
-
}
|
|
10
7
|
registerContract(childDi, contract) {
|
|
11
8
|
childDi.register(provide({
|
|
12
9
|
provide: contract,
|
|
13
10
|
useFactory: () => {
|
|
14
11
|
const value = this.appDi.get(optional(contract));
|
|
15
|
-
if (isNil(value))
|
|
12
|
+
if (isNil(value)) {
|
|
13
|
+
const { name } = childDi.get(CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
14
|
+
this.log.warn(`Contract "${contract}" for "${name}" Child App is declared but not provided in the application or contracts fallback`);
|
|
15
|
+
}
|
|
16
16
|
return value;
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
19
|
}
|
|
20
|
+
getRequestHostDi() {
|
|
21
|
+
return this.appDi;
|
|
22
|
+
}
|
|
23
|
+
getRequestChildDiManager() {
|
|
24
|
+
return this.appDi.get(optional(CHILD_APP_DI_MANAGER_TOKEN));
|
|
25
|
+
}
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
export { ChildAppContractManager };
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import type { ExtractDependencyType } from '@tinkoff/dippy';
|
|
2
1
|
import { type Container } from '@tinkoff/dippy';
|
|
3
|
-
import type { Contract
|
|
2
|
+
import type { Contract } from '@tramvai/tokens-child-app';
|
|
3
|
+
import type { ChildAppDiManager } from './contractManager.base';
|
|
4
4
|
import { BaseChildAppContractManager } from './contractManager.base';
|
|
5
|
-
type HostProvidedContracts = ExtractDependencyType<typeof HOST_PROVIDED_CONTRACTS>;
|
|
6
5
|
export declare class ChildAppContractManager extends BaseChildAppContractManager {
|
|
7
|
-
private appDi;
|
|
8
|
-
constructor({ appDi, hostProvidedContracts, }: {
|
|
9
|
-
appDi: Container;
|
|
10
|
-
hostProvidedContracts: HostProvidedContracts;
|
|
11
|
-
});
|
|
12
6
|
registerContract(childDi: Container, contract: Contract): void;
|
|
7
|
+
getRequestHostDi(): Container | null;
|
|
8
|
+
getRequestChildDiManager(): ChildAppDiManager | null;
|
|
13
9
|
}
|
|
14
|
-
export {};
|
|
15
10
|
//# sourceMappingURL=contractManager.browser.d.ts.map
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import type { DI_TOKEN, ExtractDependencyType } from '@tinkoff/dippy';
|
|
2
2
|
import { type Container } from '@tinkoff/dippy';
|
|
3
|
-
import type { Contract
|
|
3
|
+
import type { Contract } from '@tramvai/tokens-child-app';
|
|
4
4
|
import type { ASYNC_LOCAL_STORAGE_TOKEN } from '@tramvai/tokens-common';
|
|
5
|
+
import type { ChildAppDiManager, HostProvidedContracts, HostRequiredContracts, Logger } from './contractManager.base';
|
|
5
6
|
import { BaseChildAppContractManager } from './contractManager.base';
|
|
6
7
|
declare module '@tramvai/tokens-common' {
|
|
7
8
|
interface AsyncLocalStorageState {
|
|
8
9
|
tramvaiRequestDi?: ExtractDependencyType<typeof DI_TOKEN>;
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
|
-
type HostProvidedContracts = ExtractDependencyType<typeof HOST_PROVIDED_CONTRACTS>;
|
|
12
12
|
type AsyncLocalStorageType = ExtractDependencyType<typeof ASYNC_LOCAL_STORAGE_TOKEN>;
|
|
13
13
|
export declare class ChildAppContractManager extends BaseChildAppContractManager {
|
|
14
|
-
private appDi;
|
|
15
14
|
private asyncLocalStorage;
|
|
16
|
-
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, }: {
|
|
15
|
+
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, hostRequiredContracts, logger, }: {
|
|
17
16
|
appDi: Container;
|
|
18
17
|
asyncLocalStorage: AsyncLocalStorageType;
|
|
19
|
-
hostProvidedContracts: HostProvidedContracts;
|
|
18
|
+
hostProvidedContracts: HostProvidedContracts | null;
|
|
19
|
+
hostRequiredContracts: HostRequiredContracts | null;
|
|
20
|
+
logger: Logger;
|
|
20
21
|
});
|
|
21
22
|
registerContract(childDi: Container, contract: Contract): void;
|
|
23
|
+
getRequestHostDi(): Container | null;
|
|
24
|
+
getRequestChildDiManager(): ChildAppDiManager | null;
|
|
22
25
|
}
|
|
23
26
|
export {};
|
|
24
27
|
//# sourceMappingURL=contractManager.server.d.ts.map
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import isNil from '@tinkoff/utils/is/nil';
|
|
2
2
|
import { provide, optional } from '@tinkoff/dippy';
|
|
3
|
+
import { CHILD_APP_INTERNAL_CONFIG_TOKEN, CHILD_APP_DI_MANAGER_TOKEN } from '@tramvai/tokens-child-app';
|
|
3
4
|
import { BaseChildAppContractManager } from './contractManager.base.es.js';
|
|
4
5
|
|
|
5
6
|
class ChildAppContractManager extends BaseChildAppContractManager {
|
|
6
|
-
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, }) {
|
|
7
|
-
super({
|
|
8
|
-
|
|
7
|
+
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
8
|
+
super({
|
|
9
|
+
appDi,
|
|
10
|
+
hostProvidedContracts,
|
|
11
|
+
hostRequiredContracts,
|
|
12
|
+
logger,
|
|
13
|
+
});
|
|
9
14
|
this.asyncLocalStorage = asyncLocalStorage;
|
|
10
15
|
}
|
|
11
16
|
registerContract(childDi, contract) {
|
|
@@ -14,12 +19,24 @@ class ChildAppContractManager extends BaseChildAppContractManager {
|
|
|
14
19
|
useFactory: () => {
|
|
15
20
|
var _a, _b, _c;
|
|
16
21
|
const value = (_c = (_b = (_a = this.asyncLocalStorage.getStore()) === null || _a === void 0 ? void 0 : _a.tramvaiRequestDi) === null || _b === void 0 ? void 0 : _b.get(optional(contract))) !== null && _c !== void 0 ? _c : this.appDi.get(optional(contract));
|
|
17
|
-
if (isNil(value))
|
|
22
|
+
if (isNil(value)) {
|
|
23
|
+
const { name } = childDi.get(CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
24
|
+
this.log.warn(`Contract "${contract}" for "${name}" Child App is declared but not provided in the application or contracts fallback`);
|
|
25
|
+
}
|
|
18
26
|
// TODO: Request scoped contrace is resolved in Singleton scope - what should we do?
|
|
19
27
|
return value;
|
|
20
28
|
},
|
|
21
29
|
}));
|
|
22
30
|
}
|
|
31
|
+
getRequestHostDi() {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
return (_b = (_a = this.asyncLocalStorage.getStore()) === null || _a === void 0 ? void 0 : _a.tramvaiRequestDi) !== null && _b !== void 0 ? _b : null;
|
|
34
|
+
}
|
|
35
|
+
getRequestChildDiManager() {
|
|
36
|
+
var _a, _b, _c;
|
|
37
|
+
return ((_c = (_b = (_a = this.asyncLocalStorage
|
|
38
|
+
.getStore()) === null || _a === void 0 ? void 0 : _a.tramvaiRequestDi) === null || _b === void 0 ? void 0 : _b.get(optional(CHILD_APP_DI_MANAGER_TOKEN))) !== null && _c !== void 0 ? _c : null);
|
|
39
|
+
}
|
|
23
40
|
}
|
|
24
41
|
|
|
25
42
|
export { ChildAppContractManager };
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var isNil = require('@tinkoff/utils/is/nil');
|
|
6
6
|
var dippy = require('@tinkoff/dippy');
|
|
7
|
+
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
7
8
|
var contractManager_base = require('./contractManager.base.js');
|
|
8
9
|
|
|
9
10
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -11,9 +12,13 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
11
12
|
var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
|
|
12
13
|
|
|
13
14
|
class ChildAppContractManager extends contractManager_base.BaseChildAppContractManager {
|
|
14
|
-
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, }) {
|
|
15
|
-
super({
|
|
16
|
-
|
|
15
|
+
constructor({ appDi, asyncLocalStorage, hostProvidedContracts, hostRequiredContracts, logger, }) {
|
|
16
|
+
super({
|
|
17
|
+
appDi,
|
|
18
|
+
hostProvidedContracts,
|
|
19
|
+
hostRequiredContracts,
|
|
20
|
+
logger,
|
|
21
|
+
});
|
|
17
22
|
this.asyncLocalStorage = asyncLocalStorage;
|
|
18
23
|
}
|
|
19
24
|
registerContract(childDi, contract) {
|
|
@@ -22,12 +27,24 @@ class ChildAppContractManager extends contractManager_base.BaseChildAppContractM
|
|
|
22
27
|
useFactory: () => {
|
|
23
28
|
var _a, _b, _c;
|
|
24
29
|
const value = (_c = (_b = (_a = this.asyncLocalStorage.getStore()) === null || _a === void 0 ? void 0 : _a.tramvaiRequestDi) === null || _b === void 0 ? void 0 : _b.get(dippy.optional(contract))) !== null && _c !== void 0 ? _c : this.appDi.get(dippy.optional(contract));
|
|
25
|
-
if (isNil__default["default"](value))
|
|
30
|
+
if (isNil__default["default"](value)) {
|
|
31
|
+
const { name } = childDi.get(tokensChildApp.CHILD_APP_INTERNAL_CONFIG_TOKEN);
|
|
32
|
+
this.log.warn(`Contract "${contract}" for "${name}" Child App is declared but not provided in the application or contracts fallback`);
|
|
33
|
+
}
|
|
26
34
|
// TODO: Request scoped contrace is resolved in Singleton scope - what should we do?
|
|
27
35
|
return value;
|
|
28
36
|
},
|
|
29
37
|
}));
|
|
30
38
|
}
|
|
39
|
+
getRequestHostDi() {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
return (_b = (_a = this.asyncLocalStorage.getStore()) === null || _a === void 0 ? void 0 : _a.tramvaiRequestDi) !== null && _b !== void 0 ? _b : null;
|
|
42
|
+
}
|
|
43
|
+
getRequestChildDiManager() {
|
|
44
|
+
var _a, _b, _c;
|
|
45
|
+
return ((_c = (_b = (_a = this.asyncLocalStorage
|
|
46
|
+
.getStore()) === null || _a === void 0 ? void 0 : _a.tramvaiRequestDi) === null || _b === void 0 ? void 0 : _b.get(dippy.optional(tokensChildApp.CHILD_APP_DI_MANAGER_TOKEN))) !== null && _c !== void 0 ? _c : null);
|
|
47
|
+
}
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
exports.ChildAppContractManager = ChildAppContractManager;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from '@tramvai/tokens-child-app';
|
|
2
|
+
export { ChildApp } from './shared/react/component.browser.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* only for type-checking, simple way to fail application build if contracts are not valid
|
|
6
|
+
*
|
|
7
|
+
* @example `Assert({} as ContractsValidation)`
|
|
8
|
+
*/
|
|
9
|
+
const Assert = (t) => { };
|
|
10
|
+
|
|
11
|
+
export { Assert };
|
package/lib/export.d.ts
CHANGED
|
@@ -1,3 +1,54 @@
|
|
|
1
|
+
import type { TokenInterface } from '@tinkoff/dippy';
|
|
1
2
|
export * from '@tramvai/tokens-child-app';
|
|
2
3
|
export { ChildApp } from './shared/react/component';
|
|
4
|
+
export interface TypedContractsRequired {
|
|
5
|
+
}
|
|
6
|
+
export interface TypedContractsProvided {
|
|
7
|
+
}
|
|
8
|
+
export interface TypedContracts {
|
|
9
|
+
required: TypedContractsRequired;
|
|
10
|
+
provided: TypedContractsProvided;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* opaque types for unknown symbols will not be expanded (in error message)
|
|
14
|
+
*/
|
|
15
|
+
declare const errorTag: unique symbol;
|
|
16
|
+
export type TypesError<T> = {
|
|
17
|
+
[errorTag]: T;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* expand generic types one level down (in error message)
|
|
21
|
+
*/
|
|
22
|
+
type Prettify<T> = T extends Record<string, any> ? {} & {
|
|
23
|
+
[P in keyof T]: T[P];
|
|
24
|
+
} : {} & T;
|
|
25
|
+
/**
|
|
26
|
+
* exclude keys with `never` value from records
|
|
27
|
+
*/
|
|
28
|
+
type OmitNever<T> = {
|
|
29
|
+
[K in keyof T as T[K] extends never ? never : K]: T[K];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* validate required and provided contracts, `TypesError` returns on failure
|
|
33
|
+
*/
|
|
34
|
+
export type ContractsValidation = TypedContracts extends {
|
|
35
|
+
required: TypedContractsRequired;
|
|
36
|
+
provided: TypedContractsRequired;
|
|
37
|
+
} ? TypedContracts : TypesError<Prettify<OmitNever<{
|
|
38
|
+
[key in keyof Omit<TypedContracts['required'], keyof TypedContracts['provided']>]: {
|
|
39
|
+
message: `Contract is not provided`;
|
|
40
|
+
};
|
|
41
|
+
}> & OmitNever<{
|
|
42
|
+
[key in keyof TypedContracts['provided']]: TypedContracts['provided'][key] extends TypedContracts['required'][key] ? never : {
|
|
43
|
+
message: `Contract is incompatible`;
|
|
44
|
+
expected: TypedContracts['required'][key] extends TokenInterface<infer T> ? T : TypedContracts['required'][key];
|
|
45
|
+
actual: TypedContracts['provided'][key] extends TokenInterface<infer T> ? T : TypedContracts['provided'][key];
|
|
46
|
+
};
|
|
47
|
+
}>>>;
|
|
48
|
+
/**
|
|
49
|
+
* only for type-checking, simple way to fail application build if contracts are not valid
|
|
50
|
+
*
|
|
51
|
+
* @example `Assert({} as ContractsValidation)`
|
|
52
|
+
*/
|
|
53
|
+
export declare const Assert: <T>(t: T extends TypesError<any> ? never : T) => void;
|
|
3
54
|
//# sourceMappingURL=export.d.ts.map
|
package/lib/export.es.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from '@tramvai/tokens-child-app';
|
|
2
|
+
export { ChildApp } from './shared/react/component.es.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* only for type-checking, simple way to fail application build if contracts are not valid
|
|
6
|
+
*
|
|
7
|
+
* @example `Assert({} as ContractsValidation)`
|
|
8
|
+
*/
|
|
9
|
+
const Assert = (t) => { };
|
|
10
|
+
|
|
11
|
+
export { Assert };
|
package/lib/export.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
6
|
+
var component = require('./shared/react/component.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* only for type-checking, simple way to fail application build if contracts are not valid
|
|
10
|
+
*
|
|
11
|
+
* @example `Assert({} as ContractsValidation)`
|
|
12
|
+
*/
|
|
13
|
+
const Assert = (t) => { };
|
|
14
|
+
|
|
15
|
+
exports.ChildApp = component.ChildApp;
|
|
16
|
+
exports.Assert = Assert;
|
|
17
|
+
Object.keys(tokensChildApp).forEach(function (k) {
|
|
18
|
+
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return tokensChildApp[k]; }
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -3,7 +3,7 @@ import { Scope, optional, DI_TOKEN } from '@tinkoff/dippy';
|
|
|
3
3
|
import { provide, commandLineListTokens } from '@tramvai/core';
|
|
4
4
|
import { ENV_USED_TOKEN, LOGGER_TOKEN, CREATE_CACHE_TOKEN, ENV_MANAGER_TOKEN, STORE_TOKEN, ASYNC_LOCAL_STORAGE_TOKEN } from '@tramvai/tokens-common';
|
|
5
5
|
import { RESOURCES_REGISTRY, RENDER_SLOTS, ResourceType, ResourceSlot, RENDER_FLOW_AFTER_TOKEN, REACT_SERVER_RENDER_MODE, EXTEND_RENDER } from '@tramvai/tokens-render';
|
|
6
|
-
import { CHILD_APP_LOADER_TOKEN, CHILD_APP_STATE_MANAGER_TOKEN, CHILD_APP_DI_MANAGER_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_RENDER_MANAGER_TOKEN, CHILD_APP_CONTRACT_MANAGER, HOST_PROVIDED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
6
|
+
import { CHILD_APP_LOADER_TOKEN, CHILD_APP_STATE_MANAGER_TOKEN, CHILD_APP_DI_MANAGER_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_RENDER_MANAGER_TOKEN, CHILD_APP_CONTRACT_MANAGER, HOST_PROVIDED_CONTRACTS, HOST_REQUIRED_CONTRACTS } from '@tramvai/tokens-child-app';
|
|
7
7
|
import { safeStringify } from '@tramvai/safe-strings';
|
|
8
8
|
import { ServerLoader } from './loader.es.js';
|
|
9
9
|
import { PreloadManager } from './preload.es.js';
|
|
@@ -146,7 +146,9 @@ const serverProviders = [
|
|
|
146
146
|
deps: {
|
|
147
147
|
appDi: DI_TOKEN,
|
|
148
148
|
asyncLocalStorage: ASYNC_LOCAL_STORAGE_TOKEN,
|
|
149
|
-
hostProvidedContracts: HOST_PROVIDED_CONTRACTS,
|
|
149
|
+
hostProvidedContracts: optional(HOST_PROVIDED_CONTRACTS),
|
|
150
|
+
hostRequiredContracts: optional(HOST_REQUIRED_CONTRACTS),
|
|
151
|
+
logger: LOGGER_TOKEN,
|
|
150
152
|
},
|
|
151
153
|
}),
|
|
152
154
|
];
|
package/lib/server/providers.js
CHANGED
|
@@ -150,7 +150,9 @@ const serverProviders = [
|
|
|
150
150
|
deps: {
|
|
151
151
|
appDi: dippy.DI_TOKEN,
|
|
152
152
|
asyncLocalStorage: tokensCommon.ASYNC_LOCAL_STORAGE_TOKEN,
|
|
153
|
-
hostProvidedContracts: tokensChildApp.HOST_PROVIDED_CONTRACTS,
|
|
153
|
+
hostProvidedContracts: dippy.optional(tokensChildApp.HOST_PROVIDED_CONTRACTS),
|
|
154
|
+
hostRequiredContracts: dippy.optional(tokensChildApp.HOST_REQUIRED_CONTRACTS),
|
|
155
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
154
156
|
},
|
|
155
157
|
}),
|
|
156
158
|
];
|
package/lib/server.es.js
CHANGED
|
@@ -2,8 +2,9 @@ import { __decorate } from 'tslib';
|
|
|
2
2
|
import { Module } from '@tramvai/core';
|
|
3
3
|
import { sharedProviders } from './shared/providers.es.js';
|
|
4
4
|
import { serverProviders } from './server/providers.es.js';
|
|
5
|
-
export
|
|
5
|
+
export { Assert } from './export.es.js';
|
|
6
6
|
export { ChildApp } from './shared/react/component.es.js';
|
|
7
|
+
export * from '@tramvai/tokens-child-app';
|
|
7
8
|
|
|
8
9
|
let ChildAppModule = class ChildAppModule {
|
|
9
10
|
};
|
package/lib/server.js
CHANGED
|
@@ -6,8 +6,9 @@ var tslib = require('tslib');
|
|
|
6
6
|
var core = require('@tramvai/core');
|
|
7
7
|
var providers = require('./shared/providers.js');
|
|
8
8
|
var providers$1 = require('./server/providers.js');
|
|
9
|
-
var
|
|
9
|
+
var _export = require('./export.js');
|
|
10
10
|
var component = require('./shared/react/component.js');
|
|
11
|
+
var tokensChildApp = require('@tramvai/tokens-child-app');
|
|
11
12
|
|
|
12
13
|
exports.ChildAppModule = class ChildAppModule {
|
|
13
14
|
};
|
|
@@ -18,6 +19,7 @@ exports.ChildAppModule = tslib.__decorate([
|
|
|
18
19
|
})
|
|
19
20
|
], exports.ChildAppModule);
|
|
20
21
|
|
|
22
|
+
exports.Assert = _export.Assert;
|
|
21
23
|
exports.ChildApp = component.ChildApp;
|
|
22
24
|
Object.keys(tokensChildApp).forEach(function (k) {
|
|
23
25
|
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
@@ -100,6 +100,7 @@ class SingletonDiManager {
|
|
|
100
100
|
});
|
|
101
101
|
if (isolateDi) {
|
|
102
102
|
this.contractManager.registerChildContracts(di);
|
|
103
|
+
this.contractManager.validateChildProvidedContracts(di);
|
|
103
104
|
}
|
|
104
105
|
const borrowTokens = di.get({ token: CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN, optional: true });
|
|
105
106
|
if (borrowTokens) {
|
|
@@ -100,6 +100,7 @@ class SingletonDiManager {
|
|
|
100
100
|
});
|
|
101
101
|
if (isolateDi) {
|
|
102
102
|
this.contractManager.registerChildContracts(di);
|
|
103
|
+
this.contractManager.validateChildProvidedContracts(di);
|
|
103
104
|
}
|
|
104
105
|
const borrowTokens = di.get({ token: CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN, optional: true });
|
|
105
106
|
if (borrowTokens) {
|
|
@@ -108,6 +108,7 @@ class SingletonDiManager {
|
|
|
108
108
|
});
|
|
109
109
|
if (isolateDi) {
|
|
110
110
|
this.contractManager.registerChildContracts(di);
|
|
111
|
+
this.contractManager.validateChildProvidedContracts(di);
|
|
111
112
|
}
|
|
112
113
|
const borrowTokens = di.get({ token: tokensChildApp.CHILD_APP_INTERNAL_ROOT_DI_BORROW_TOKEN, optional: true });
|
|
113
114
|
if (borrowTokens) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-child-app",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.24.0",
|
|
4
4
|
"description": "Module for child apps",
|
|
5
5
|
"browser": {
|
|
6
6
|
"./lib/server.js": "./lib/browser.js",
|
|
@@ -33,23 +33,23 @@
|
|
|
33
33
|
"@tinkoff/env-validators": "0.3.1",
|
|
34
34
|
"@tinkoff/module-loader-client": "0.6.3",
|
|
35
35
|
"@tinkoff/module-loader-server": "0.7.2",
|
|
36
|
-
"@tramvai/module-common": "4.
|
|
36
|
+
"@tramvai/module-common": "4.24.0",
|
|
37
37
|
"@tinkoff/url": "0.10.1",
|
|
38
|
-
"@tramvai/child-app-core": "4.
|
|
38
|
+
"@tramvai/child-app-core": "4.24.0",
|
|
39
39
|
"@tramvai/safe-strings": "0.7.2",
|
|
40
|
-
"@tramvai/tokens-child-app": "4.
|
|
40
|
+
"@tramvai/tokens-child-app": "4.24.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@tinkoff/dippy": "0.10.
|
|
45
|
-
"@tinkoff/router": "0.4.
|
|
44
|
+
"@tinkoff/dippy": "0.10.8",
|
|
45
|
+
"@tinkoff/router": "0.4.77",
|
|
46
46
|
"@tinkoff/utils": "^2.1.2",
|
|
47
|
-
"@tramvai/core": "4.
|
|
48
|
-
"@tramvai/state": "4.
|
|
49
|
-
"@tramvai/react": "4.
|
|
50
|
-
"@tramvai/tokens-common": "4.
|
|
51
|
-
"@tramvai/tokens-render": "4.
|
|
52
|
-
"@tramvai/tokens-router": "4.
|
|
47
|
+
"@tramvai/core": "4.24.0",
|
|
48
|
+
"@tramvai/state": "4.24.0",
|
|
49
|
+
"@tramvai/react": "4.24.0",
|
|
50
|
+
"@tramvai/tokens-common": "4.24.0",
|
|
51
|
+
"@tramvai/tokens-render": "4.24.0",
|
|
52
|
+
"@tramvai/tokens-router": "4.24.0",
|
|
53
53
|
"react": ">=16.14.0",
|
|
54
54
|
"react-dom": ">=16.14.0",
|
|
55
55
|
"object-assign": "^4.1.1",
|