@tramvai/module-render 2.134.0 → 2.139.2
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/server/PageBuilder.d.ts +3 -1
- package/lib/server/PageBuilder.es.js +5 -2
- package/lib/server/PageBuilder.js +5 -2
- package/lib/server/ReactRenderServer.d.ts +6 -1
- package/lib/server/ReactRenderServer.es.js +44 -21
- package/lib/server/ReactRenderServer.js +44 -21
- package/lib/server.es.js +4 -0
- package/lib/server.js +4 -0
- package/package.json +15 -15
|
@@ -12,7 +12,8 @@ export declare class PageBuilder {
|
|
|
12
12
|
private renderFlowAfter;
|
|
13
13
|
private log;
|
|
14
14
|
private fetchWebpackStats;
|
|
15
|
-
|
|
15
|
+
private di;
|
|
16
|
+
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, }: {
|
|
16
17
|
renderSlots: any;
|
|
17
18
|
pageService: any;
|
|
18
19
|
resourcesRegistry: any;
|
|
@@ -25,6 +26,7 @@ export declare class PageBuilder {
|
|
|
25
26
|
renderFlowAfter: any;
|
|
26
27
|
logger: any;
|
|
27
28
|
fetchWebpackStats: any;
|
|
29
|
+
di: any;
|
|
28
30
|
});
|
|
29
31
|
flow(): Promise<string>;
|
|
30
32
|
dehydrateState(): void;
|
|
@@ -20,7 +20,7 @@ const mapResourcesToSlots = (resources) => resources.reduce((acc, resource) => {
|
|
|
20
20
|
return acc;
|
|
21
21
|
}, {});
|
|
22
22
|
class PageBuilder {
|
|
23
|
-
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, }) {
|
|
23
|
+
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, }) {
|
|
24
24
|
this.htmlAttrs = htmlAttrs;
|
|
25
25
|
this.renderSlots = flatten(renderSlots || []);
|
|
26
26
|
this.pageService = pageService;
|
|
@@ -33,6 +33,7 @@ class PageBuilder {
|
|
|
33
33
|
this.renderFlowAfter = renderFlowAfter || [];
|
|
34
34
|
this.log = logger('page-builder');
|
|
35
35
|
this.fetchWebpackStats = fetchWebpackStats;
|
|
36
|
+
this.di = di;
|
|
36
37
|
}
|
|
37
38
|
async flow() {
|
|
38
39
|
const stats = await this.fetchWebpackStats({ modern: this.modern });
|
|
@@ -91,10 +92,12 @@ class PageBuilder {
|
|
|
91
92
|
}
|
|
92
93
|
async renderApp(extractor) {
|
|
93
94
|
const html = await this.reactRender.render(extractor);
|
|
95
|
+
const appHtmlAttrs = formatAttributes(this.htmlAttrs, 'app');
|
|
96
|
+
this.di.register({ provide: 'tramvai app html attributes', useValue: appHtmlAttrs });
|
|
94
97
|
this.renderSlots = this.renderSlots.concat({
|
|
95
98
|
type: ResourceType.asIs,
|
|
96
99
|
slot: ResourceSlot.REACT_RENDER,
|
|
97
|
-
payload: `<div ${
|
|
100
|
+
payload: `<div ${appHtmlAttrs}>${html}</div>`,
|
|
98
101
|
});
|
|
99
102
|
}
|
|
100
103
|
}
|
|
@@ -28,7 +28,7 @@ const mapResourcesToSlots = (resources) => resources.reduce((acc, resource) => {
|
|
|
28
28
|
return acc;
|
|
29
29
|
}, {});
|
|
30
30
|
class PageBuilder {
|
|
31
|
-
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, }) {
|
|
31
|
+
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, fetchWebpackStats, di, }) {
|
|
32
32
|
this.htmlAttrs = htmlAttrs;
|
|
33
33
|
this.renderSlots = flatten__default["default"](renderSlots || []);
|
|
34
34
|
this.pageService = pageService;
|
|
@@ -41,6 +41,7 @@ class PageBuilder {
|
|
|
41
41
|
this.renderFlowAfter = renderFlowAfter || [];
|
|
42
42
|
this.log = logger('page-builder');
|
|
43
43
|
this.fetchWebpackStats = fetchWebpackStats;
|
|
44
|
+
this.di = di;
|
|
44
45
|
}
|
|
45
46
|
async flow() {
|
|
46
47
|
const stats = await this.fetchWebpackStats({ modern: this.modern });
|
|
@@ -99,10 +100,12 @@ class PageBuilder {
|
|
|
99
100
|
}
|
|
100
101
|
async renderApp(extractor) {
|
|
101
102
|
const html = await this.reactRender.render(extractor);
|
|
103
|
+
const appHtmlAttrs = utils.formatAttributes(this.htmlAttrs, 'app');
|
|
104
|
+
this.di.register({ provide: 'tramvai app html attributes', useValue: appHtmlAttrs });
|
|
102
105
|
this.renderSlots = this.renderSlots.concat({
|
|
103
106
|
type: tokensRender.ResourceType.asIs,
|
|
104
107
|
slot: tokensRender.ResourceSlot.REACT_RENDER,
|
|
105
|
-
payload: `<div ${
|
|
108
|
+
payload: `<div ${appHtmlAttrs}>${html}</div>`,
|
|
106
109
|
});
|
|
107
110
|
}
|
|
108
111
|
}
|
|
@@ -3,20 +3,25 @@ import type { DI_TOKEN } from '@tramvai/core';
|
|
|
3
3
|
import type { CONTEXT_TOKEN, LOGGER_TOKEN } from '@tramvai/module-common';
|
|
4
4
|
import type { EXTEND_RENDER, CUSTOM_RENDER, REACT_SERVER_RENDER_MODE } from '@tramvai/tokens-render';
|
|
5
5
|
import type { ChunkExtractor } from '@loadable/server';
|
|
6
|
+
import type { SERVER_RESPONSE_STREAM, SERVER_RESPONSE_TASK_MANAGER } from '@tramvai/tokens-server-private';
|
|
6
7
|
export declare class ReactRenderServer {
|
|
7
8
|
customRender: typeof CUSTOM_RENDER;
|
|
8
9
|
extendRender: ExtractDependencyType<typeof EXTEND_RENDER>;
|
|
9
10
|
context: typeof CONTEXT_TOKEN;
|
|
10
11
|
di: typeof DI_TOKEN;
|
|
11
12
|
log: ReturnType<typeof LOGGER_TOKEN>;
|
|
13
|
+
responseTaskManager: typeof SERVER_RESPONSE_TASK_MANAGER;
|
|
14
|
+
responseStream: typeof SERVER_RESPONSE_STREAM;
|
|
12
15
|
renderMode: typeof REACT_SERVER_RENDER_MODE;
|
|
13
|
-
constructor({ context, customRender, extendRender, di, renderMode, logger }: {
|
|
16
|
+
constructor({ context, customRender, extendRender, di, renderMode, logger, responseTaskManager, responseStream, }: {
|
|
14
17
|
context: any;
|
|
15
18
|
customRender: any;
|
|
16
19
|
extendRender: any;
|
|
17
20
|
di: any;
|
|
18
21
|
renderMode: any;
|
|
19
22
|
logger: any;
|
|
23
|
+
responseTaskManager: any;
|
|
24
|
+
responseStream: any;
|
|
20
25
|
});
|
|
21
26
|
render(extractor: ChunkExtractor): Promise<string>;
|
|
22
27
|
}
|
|
@@ -4,32 +4,42 @@ import { renderReact } from '../react/index.es.js';
|
|
|
4
4
|
|
|
5
5
|
const RENDER_TIMEOUT = 500;
|
|
6
6
|
class HtmlWritable extends Writable {
|
|
7
|
-
constructor() {
|
|
8
|
-
super(
|
|
9
|
-
this.
|
|
10
|
-
this.
|
|
11
|
-
}
|
|
12
|
-
getHtml() {
|
|
13
|
-
return this.html;
|
|
7
|
+
constructor({ responseTaskManager, responseStream, }) {
|
|
8
|
+
super();
|
|
9
|
+
this.responseTaskManager = responseTaskManager;
|
|
10
|
+
this.responseStream = responseStream;
|
|
14
11
|
}
|
|
15
12
|
_write(chunk, encoding, callback) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const html = chunk.toString('utf-8');
|
|
14
|
+
// delay writing HTML to response stream
|
|
15
|
+
// @todo some priorities, to prevent conflicts with deferred actions scripts?
|
|
16
|
+
this.responseTaskManager.push(async () => {
|
|
17
|
+
this.responseStream.push(html);
|
|
18
|
+
});
|
|
21
19
|
callback();
|
|
22
20
|
}
|
|
23
21
|
}
|
|
22
|
+
const Deferred = () => {
|
|
23
|
+
let resolve;
|
|
24
|
+
let reject;
|
|
25
|
+
// eslint-disable-next-line promise/param-names
|
|
26
|
+
const promise = new Promise((res, rej) => {
|
|
27
|
+
resolve = res;
|
|
28
|
+
reject = rej;
|
|
29
|
+
});
|
|
30
|
+
return { promise, resolve, reject };
|
|
31
|
+
};
|
|
24
32
|
class ReactRenderServer {
|
|
25
33
|
// eslint-disable-next-line sort-class-members/sort-class-members
|
|
26
|
-
constructor({ context, customRender, extendRender, di, renderMode, logger }) {
|
|
34
|
+
constructor({ context, customRender, extendRender, di, renderMode, logger, responseTaskManager, responseStream, }) {
|
|
27
35
|
this.context = context;
|
|
28
36
|
this.customRender = customRender;
|
|
29
37
|
this.extendRender = extendRender;
|
|
30
38
|
this.di = di;
|
|
31
39
|
this.renderMode = renderMode;
|
|
32
40
|
this.log = logger('module-render');
|
|
41
|
+
this.responseTaskManager = responseTaskManager;
|
|
42
|
+
this.responseStream = responseStream;
|
|
33
43
|
}
|
|
34
44
|
render(extractor) {
|
|
35
45
|
var _a;
|
|
@@ -44,23 +54,36 @@ class ReactRenderServer {
|
|
|
44
54
|
if (process.env.__TRAMVAI_CONCURRENT_FEATURES && this.renderMode === 'streaming') {
|
|
45
55
|
return new Promise((resolve, reject) => {
|
|
46
56
|
const { renderToPipeableStream } = require('react-dom/server');
|
|
47
|
-
const
|
|
48
|
-
htmlWritable
|
|
49
|
-
|
|
50
|
-
});
|
|
57
|
+
const { responseTaskManager, responseStream, log } = this;
|
|
58
|
+
const htmlWritable = new HtmlWritable({ responseTaskManager, responseStream });
|
|
59
|
+
const allReadyDeferred = Deferred();
|
|
51
60
|
const start = Date.now();
|
|
52
|
-
|
|
61
|
+
// prevent sent reply before all suspended components are resolved
|
|
62
|
+
responseTaskManager.push(() => {
|
|
63
|
+
// eslint-disable-next-line promise/param-names
|
|
64
|
+
return allReadyDeferred.promise;
|
|
65
|
+
});
|
|
53
66
|
log.info({
|
|
54
67
|
event: 'streaming-render:start',
|
|
55
68
|
});
|
|
56
69
|
const { pipe, abort } = renderToPipeableStream(renderResult, {
|
|
57
|
-
|
|
70
|
+
onShellReady() {
|
|
58
71
|
log.info({
|
|
59
|
-
event: 'streaming-render:
|
|
72
|
+
event: 'streaming-render:shell-ready',
|
|
60
73
|
duration: Date.now() - start,
|
|
61
74
|
});
|
|
62
|
-
// here
|
|
75
|
+
// here all HTML are ready except suspended components
|
|
63
76
|
pipe(htmlWritable);
|
|
77
|
+
// resolve empty HTML, because we will stream it later
|
|
78
|
+
resolve('');
|
|
79
|
+
},
|
|
80
|
+
onAllReady() {
|
|
81
|
+
log.info({
|
|
82
|
+
event: 'streaming-render:all-ready',
|
|
83
|
+
duration: Date.now() - start,
|
|
84
|
+
});
|
|
85
|
+
// here all suspended components are resolved
|
|
86
|
+
allReadyDeferred.resolve();
|
|
64
87
|
},
|
|
65
88
|
onError(error) {
|
|
66
89
|
// error can be inside Suspense boundaries, this is not critical, continue rendering.
|
|
@@ -12,32 +12,42 @@ var each__default = /*#__PURE__*/_interopDefaultLegacy(each);
|
|
|
12
12
|
|
|
13
13
|
const RENDER_TIMEOUT = 500;
|
|
14
14
|
class HtmlWritable extends stream.Writable {
|
|
15
|
-
constructor() {
|
|
16
|
-
super(
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
-
}
|
|
20
|
-
getHtml() {
|
|
21
|
-
return this.html;
|
|
15
|
+
constructor({ responseTaskManager, responseStream, }) {
|
|
16
|
+
super();
|
|
17
|
+
this.responseTaskManager = responseTaskManager;
|
|
18
|
+
this.responseStream = responseStream;
|
|
22
19
|
}
|
|
23
20
|
_write(chunk, encoding, callback) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
const html = chunk.toString('utf-8');
|
|
22
|
+
// delay writing HTML to response stream
|
|
23
|
+
// @todo some priorities, to prevent conflicts with deferred actions scripts?
|
|
24
|
+
this.responseTaskManager.push(async () => {
|
|
25
|
+
this.responseStream.push(html);
|
|
26
|
+
});
|
|
29
27
|
callback();
|
|
30
28
|
}
|
|
31
29
|
}
|
|
30
|
+
const Deferred = () => {
|
|
31
|
+
let resolve;
|
|
32
|
+
let reject;
|
|
33
|
+
// eslint-disable-next-line promise/param-names
|
|
34
|
+
const promise = new Promise((res, rej) => {
|
|
35
|
+
resolve = res;
|
|
36
|
+
reject = rej;
|
|
37
|
+
});
|
|
38
|
+
return { promise, resolve, reject };
|
|
39
|
+
};
|
|
32
40
|
class ReactRenderServer {
|
|
33
41
|
// eslint-disable-next-line sort-class-members/sort-class-members
|
|
34
|
-
constructor({ context, customRender, extendRender, di, renderMode, logger }) {
|
|
42
|
+
constructor({ context, customRender, extendRender, di, renderMode, logger, responseTaskManager, responseStream, }) {
|
|
35
43
|
this.context = context;
|
|
36
44
|
this.customRender = customRender;
|
|
37
45
|
this.extendRender = extendRender;
|
|
38
46
|
this.di = di;
|
|
39
47
|
this.renderMode = renderMode;
|
|
40
48
|
this.log = logger('module-render');
|
|
49
|
+
this.responseTaskManager = responseTaskManager;
|
|
50
|
+
this.responseStream = responseStream;
|
|
41
51
|
}
|
|
42
52
|
render(extractor) {
|
|
43
53
|
var _a;
|
|
@@ -52,23 +62,36 @@ class ReactRenderServer {
|
|
|
52
62
|
if (process.env.__TRAMVAI_CONCURRENT_FEATURES && this.renderMode === 'streaming') {
|
|
53
63
|
return new Promise((resolve, reject) => {
|
|
54
64
|
const { renderToPipeableStream } = require('react-dom/server');
|
|
55
|
-
const
|
|
56
|
-
htmlWritable
|
|
57
|
-
|
|
58
|
-
});
|
|
65
|
+
const { responseTaskManager, responseStream, log } = this;
|
|
66
|
+
const htmlWritable = new HtmlWritable({ responseTaskManager, responseStream });
|
|
67
|
+
const allReadyDeferred = Deferred();
|
|
59
68
|
const start = Date.now();
|
|
60
|
-
|
|
69
|
+
// prevent sent reply before all suspended components are resolved
|
|
70
|
+
responseTaskManager.push(() => {
|
|
71
|
+
// eslint-disable-next-line promise/param-names
|
|
72
|
+
return allReadyDeferred.promise;
|
|
73
|
+
});
|
|
61
74
|
log.info({
|
|
62
75
|
event: 'streaming-render:start',
|
|
63
76
|
});
|
|
64
77
|
const { pipe, abort } = renderToPipeableStream(renderResult, {
|
|
65
|
-
|
|
78
|
+
onShellReady() {
|
|
66
79
|
log.info({
|
|
67
|
-
event: 'streaming-render:
|
|
80
|
+
event: 'streaming-render:shell-ready',
|
|
68
81
|
duration: Date.now() - start,
|
|
69
82
|
});
|
|
70
|
-
// here
|
|
83
|
+
// here all HTML are ready except suspended components
|
|
71
84
|
pipe(htmlWritable);
|
|
85
|
+
// resolve empty HTML, because we will stream it later
|
|
86
|
+
resolve('');
|
|
87
|
+
},
|
|
88
|
+
onAllReady() {
|
|
89
|
+
log.info({
|
|
90
|
+
event: 'streaming-render:all-ready',
|
|
91
|
+
duration: Date.now() - start,
|
|
92
|
+
});
|
|
93
|
+
// here all suspended components are resolved
|
|
94
|
+
allReadyDeferred.resolve();
|
|
72
95
|
},
|
|
73
96
|
onError(error) {
|
|
74
97
|
// error can be inside Suspense boundaries, this is not critical, continue rendering.
|
package/lib/server.es.js
CHANGED
|
@@ -11,6 +11,7 @@ import { isRedirectFoundError } from '@tinkoff/errors';
|
|
|
11
11
|
import { setPageErrorEvent, PageErrorStore, deserializeError } from '@tramvai/module-router';
|
|
12
12
|
export { PageErrorStore, setPageErrorEvent } from '@tramvai/module-router';
|
|
13
13
|
import { COOKIE_MANAGER_TOKEN } from '@tramvai/module-common';
|
|
14
|
+
import { SERVER_RESPONSE_TASK_MANAGER, SERVER_RESPONSE_STREAM } from '@tramvai/tokens-server-private';
|
|
14
15
|
import { ResourcesInliner } from './resourcesInliner/resourcesInliner.es.js';
|
|
15
16
|
import { RESOURCE_INLINER, RESOURCES_REGISTRY_CACHE } from './resourcesInliner/tokens.es.js';
|
|
16
17
|
import { ResourcesRegistry } from './resourcesRegistry/index.es.js';
|
|
@@ -197,6 +198,7 @@ Page Error Boundary will be rendered for the client`,
|
|
|
197
198
|
renderFlowAfter: { token: RENDER_FLOW_AFTER_TOKEN, optional: true },
|
|
198
199
|
logger: LOGGER_TOKEN,
|
|
199
200
|
fetchWebpackStats: FETCH_WEBPACK_STATS_TOKEN,
|
|
201
|
+
di: DI_TOKEN,
|
|
200
202
|
},
|
|
201
203
|
}),
|
|
202
204
|
provide({
|
|
@@ -209,6 +211,8 @@ Page Error Boundary will be rendered for the client`,
|
|
|
209
211
|
di: DI_TOKEN,
|
|
210
212
|
renderMode: { token: REACT_SERVER_RENDER_MODE, optional: true },
|
|
211
213
|
logger: LOGGER_TOKEN,
|
|
214
|
+
responseTaskManager: SERVER_RESPONSE_TASK_MANAGER,
|
|
215
|
+
responseStream: SERVER_RESPONSE_STREAM,
|
|
212
216
|
},
|
|
213
217
|
}),
|
|
214
218
|
provide({
|
package/lib/server.js
CHANGED
|
@@ -13,6 +13,7 @@ var userAgent = require('@tinkoff/user-agent');
|
|
|
13
13
|
var errors = require('@tinkoff/errors');
|
|
14
14
|
var moduleRouter = require('@tramvai/module-router');
|
|
15
15
|
var moduleCommon = require('@tramvai/module-common');
|
|
16
|
+
var tokensServerPrivate = require('@tramvai/tokens-server-private');
|
|
16
17
|
var resourcesInliner = require('./resourcesInliner/resourcesInliner.js');
|
|
17
18
|
var tokens = require('./resourcesInliner/tokens.js');
|
|
18
19
|
var index = require('./resourcesRegistry/index.js');
|
|
@@ -198,6 +199,7 @@ Page Error Boundary will be rendered for the client`,
|
|
|
198
199
|
renderFlowAfter: { token: tokensRender.RENDER_FLOW_AFTER_TOKEN, optional: true },
|
|
199
200
|
logger: tokensCommon.LOGGER_TOKEN,
|
|
200
201
|
fetchWebpackStats: tokensRender.FETCH_WEBPACK_STATS_TOKEN,
|
|
202
|
+
di: core.DI_TOKEN,
|
|
201
203
|
},
|
|
202
204
|
}),
|
|
203
205
|
core.provide({
|
|
@@ -210,6 +212,8 @@ Page Error Boundary will be rendered for the client`,
|
|
|
210
212
|
di: core.DI_TOKEN,
|
|
211
213
|
renderMode: { token: tokensRender.REACT_SERVER_RENDER_MODE, optional: true },
|
|
212
214
|
logger: tokensCommon.LOGGER_TOKEN,
|
|
215
|
+
responseTaskManager: tokensServerPrivate.SERVER_RESPONSE_TASK_MANAGER,
|
|
216
|
+
responseStream: tokensServerPrivate.SERVER_RESPONSE_STREAM,
|
|
213
217
|
},
|
|
214
218
|
}),
|
|
215
219
|
core.provide({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-render",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.139.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"browser": "lib/browser.js",
|
|
6
6
|
"main": "lib/server.js",
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"@tinkoff/layout-factory": "0.3.8",
|
|
27
27
|
"@tinkoff/errors": "0.3.8",
|
|
28
28
|
"@tinkoff/url": "0.8.6",
|
|
29
|
-
"@tinkoff/user-agent": "0.4.
|
|
30
|
-
"@tramvai/module-client-hints": "2.
|
|
31
|
-
"@tramvai/module-router": "2.
|
|
32
|
-
"@tramvai/react": "2.
|
|
29
|
+
"@tinkoff/user-agent": "0.4.408",
|
|
30
|
+
"@tramvai/module-client-hints": "2.139.2",
|
|
31
|
+
"@tramvai/module-router": "2.139.2",
|
|
32
|
+
"@tramvai/react": "2.139.2",
|
|
33
33
|
"@tramvai/safe-strings": "0.5.11",
|
|
34
|
-
"@tramvai/tokens-render": "2.
|
|
35
|
-
"@tramvai/experiments": "2.
|
|
34
|
+
"@tramvai/tokens-render": "2.139.2",
|
|
35
|
+
"@tramvai/experiments": "2.139.2",
|
|
36
36
|
"@types/loadable__server": "^5.12.6",
|
|
37
37
|
"node-fetch": "^2.6.1"
|
|
38
38
|
},
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"@tinkoff/dippy": "0.8.15",
|
|
41
41
|
"@tinkoff/utils": "^2.1.2",
|
|
42
42
|
"@tinkoff/react-hooks": "0.1.6",
|
|
43
|
-
"@tramvai/cli": "2.
|
|
44
|
-
"@tramvai/core": "2.
|
|
45
|
-
"@tramvai/module-common": "2.
|
|
46
|
-
"@tramvai/state": "2.
|
|
47
|
-
"@tramvai/test-helpers": "2.
|
|
48
|
-
"@tramvai/tokens-common": "2.
|
|
49
|
-
"@tramvai/tokens-router": "2.
|
|
50
|
-
"@tramvai/tokens-server-private": "2.
|
|
43
|
+
"@tramvai/cli": "2.139.2",
|
|
44
|
+
"@tramvai/core": "2.139.2",
|
|
45
|
+
"@tramvai/module-common": "2.139.2",
|
|
46
|
+
"@tramvai/state": "2.139.2",
|
|
47
|
+
"@tramvai/test-helpers": "2.139.2",
|
|
48
|
+
"@tramvai/tokens-common": "2.139.2",
|
|
49
|
+
"@tramvai/tokens-router": "2.139.2",
|
|
50
|
+
"@tramvai/tokens-server-private": "2.139.2",
|
|
51
51
|
"express": "^4.17.1",
|
|
52
52
|
"prop-types": "^15.6.2",
|
|
53
53
|
"react": ">=16.14.0",
|