@tramvai/module-render 2.94.7 → 2.94.9
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/resourcesInliner/resourcesInliner.d.ts +2 -0
- package/lib/resourcesInliner/resourcesInliner.es.js +27 -5
- package/lib/resourcesInliner/resourcesInliner.js +27 -5
- package/lib/resourcesRegistry/index.d.ts +1 -0
- package/lib/resourcesRegistry/index.es.js +6 -0
- package/lib/resourcesRegistry/index.js +6 -0
- package/lib/server/PageBuilder.es.js +3 -0
- package/lib/server/PageBuilder.js +3 -0
- package/package.json +16 -16
- package/tests.js +9 -1
|
@@ -3,6 +3,7 @@ export interface ResourcesInlinerType {
|
|
|
3
3
|
shouldAddResource(resource: PageResource): boolean;
|
|
4
4
|
shouldInline(resource: PageResource): boolean;
|
|
5
5
|
inlineResource(resource: PageResource): PageResource[];
|
|
6
|
+
prefetchResource(resource: PageResource): Promise<void>;
|
|
6
7
|
}
|
|
7
8
|
export declare class ResourcesInliner implements ResourcesInlinerType {
|
|
8
9
|
private resourceInlineThreshold?;
|
|
@@ -21,4 +22,5 @@ export declare class ResourcesInliner implements ResourcesInlinerType {
|
|
|
21
22
|
shouldAddResource(resource: PageResource): boolean;
|
|
22
23
|
shouldInline(resource: PageResource): boolean;
|
|
23
24
|
inlineResource(resource: PageResource): PageResource[];
|
|
25
|
+
prefetchResource(resource: PageResource): Promise<void>;
|
|
24
26
|
}
|
|
@@ -6,9 +6,10 @@ import { getFile, getFileContentLength } from './externalFilesHelper.es.js';
|
|
|
6
6
|
import { processFile } from './fileProcessor.es.js';
|
|
7
7
|
|
|
8
8
|
const INTERNAL_CACHE_SIZE = 50;
|
|
9
|
+
const TRAMVAI_CLI_ASSETS_PREFIX = `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
|
|
9
10
|
const ASSETS_PREFIX = process.env.NODE_ENV === 'development' &&
|
|
10
11
|
(process.env.ASSETS_PREFIX === 'static' || !process.env.ASSETS_PREFIX)
|
|
11
|
-
?
|
|
12
|
+
? TRAMVAI_CLI_ASSETS_PREFIX
|
|
12
13
|
: process.env.ASSETS_PREFIX;
|
|
13
14
|
const getInlineType = (type) => {
|
|
14
15
|
switch (type) {
|
|
@@ -24,7 +25,11 @@ const getResourceUrl = (resource) => {
|
|
|
24
25
|
if (isEmpty(resource.payload) || !isAbsoluteUrl(resource.payload)) {
|
|
25
26
|
return undefined;
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
+
let result = resource.payload.startsWith('//') ? `https:${resource.payload}` : resource.payload;
|
|
29
|
+
if (process.env.TRAMVAI_CLI_COMMAND === 'static' && result.startsWith(ASSETS_PREFIX)) {
|
|
30
|
+
result = result.replace(ASSETS_PREFIX, TRAMVAI_CLI_ASSETS_PREFIX);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
28
33
|
};
|
|
29
34
|
class ResourcesInliner {
|
|
30
35
|
constructor({ resourcesRegistryCache, resourceInlineThreshold, logger }) {
|
|
@@ -64,7 +69,7 @@ class ResourcesInliner {
|
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
};
|
|
67
|
-
this.scheduleFileSizeLoad = async (resource, resourceInlineThreshold) => {
|
|
72
|
+
this.scheduleFileSizeLoad = async (resource, resourceInlineThreshold, waitForFileLoad) => {
|
|
68
73
|
const url = getResourceUrl(resource);
|
|
69
74
|
const requestKey = `size${url}`;
|
|
70
75
|
const result = this.resourcesRegistryCache.sizeCache.get(url);
|
|
@@ -80,7 +85,10 @@ class ResourcesInliner {
|
|
|
80
85
|
this.resourcesRegistryCache.sizeCache.set(url, size);
|
|
81
86
|
}
|
|
82
87
|
if (size < resourceInlineThreshold) {
|
|
83
|
-
this.scheduleFileLoad(resource, resourceInlineThreshold);
|
|
88
|
+
const promise = this.scheduleFileLoad(resource, resourceInlineThreshold);
|
|
89
|
+
if (waitForFileLoad) {
|
|
90
|
+
await promise;
|
|
91
|
+
}
|
|
84
92
|
}
|
|
85
93
|
}
|
|
86
94
|
catch (error) {
|
|
@@ -103,7 +111,9 @@ class ResourcesInliner {
|
|
|
103
111
|
this.log = logger('resources-inliner');
|
|
104
112
|
}
|
|
105
113
|
getFilesCache(url) {
|
|
106
|
-
if (url.startsWith(ASSETS_PREFIX)
|
|
114
|
+
if (url.startsWith(ASSETS_PREFIX) ||
|
|
115
|
+
// reverse logic for `static` command in `getResourceUrl` method
|
|
116
|
+
(process.env.TRAMVAI_CLI_COMMAND === 'static' && url.startsWith(TRAMVAI_CLI_ASSETS_PREFIX))) {
|
|
107
117
|
// internal resources are resources generated by the current app itself
|
|
108
118
|
// these kind of resources are pretty static and won't be changed while app is running
|
|
109
119
|
// so we can cache it with bare Map and do not care about how to cleanup cache from outdated entries
|
|
@@ -200,6 +210,18 @@ class ResourcesInliner {
|
|
|
200
210
|
}
|
|
201
211
|
return result;
|
|
202
212
|
}
|
|
213
|
+
async prefetchResource(resource) {
|
|
214
|
+
const url = getResourceUrl(resource);
|
|
215
|
+
const resourceInlineThreshold = this.resourceInlineThreshold.threshold;
|
|
216
|
+
if (isUndefined(url) ||
|
|
217
|
+
isUndefined(resourceInlineThreshold) ||
|
|
218
|
+
this.resourcesRegistryCache.disabledUrlsCache.has(url)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (!this.resourcesRegistryCache.sizeCache.has(url)) {
|
|
222
|
+
await this.scheduleFileSizeLoad(resource, resourceInlineThreshold, true);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
203
225
|
}
|
|
204
226
|
|
|
205
227
|
export { ResourcesInliner };
|
|
@@ -15,9 +15,10 @@ var isUndefined__default = /*#__PURE__*/_interopDefaultLegacy(isUndefined);
|
|
|
15
15
|
var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
|
|
16
16
|
|
|
17
17
|
const INTERNAL_CACHE_SIZE = 50;
|
|
18
|
+
const TRAMVAI_CLI_ASSETS_PREFIX = `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
|
|
18
19
|
const ASSETS_PREFIX = process.env.NODE_ENV === 'development' &&
|
|
19
20
|
(process.env.ASSETS_PREFIX === 'static' || !process.env.ASSETS_PREFIX)
|
|
20
|
-
?
|
|
21
|
+
? TRAMVAI_CLI_ASSETS_PREFIX
|
|
21
22
|
: process.env.ASSETS_PREFIX;
|
|
22
23
|
const getInlineType = (type) => {
|
|
23
24
|
switch (type) {
|
|
@@ -33,7 +34,11 @@ const getResourceUrl = (resource) => {
|
|
|
33
34
|
if (isEmpty__default["default"](resource.payload) || !url.isAbsoluteUrl(resource.payload)) {
|
|
34
35
|
return undefined;
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
+
let result = resource.payload.startsWith('//') ? `https:${resource.payload}` : resource.payload;
|
|
38
|
+
if (process.env.TRAMVAI_CLI_COMMAND === 'static' && result.startsWith(ASSETS_PREFIX)) {
|
|
39
|
+
result = result.replace(ASSETS_PREFIX, TRAMVAI_CLI_ASSETS_PREFIX);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
37
42
|
};
|
|
38
43
|
class ResourcesInliner {
|
|
39
44
|
constructor({ resourcesRegistryCache, resourceInlineThreshold, logger }) {
|
|
@@ -73,7 +78,7 @@ class ResourcesInliner {
|
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
};
|
|
76
|
-
this.scheduleFileSizeLoad = async (resource, resourceInlineThreshold) => {
|
|
81
|
+
this.scheduleFileSizeLoad = async (resource, resourceInlineThreshold, waitForFileLoad) => {
|
|
77
82
|
const url = getResourceUrl(resource);
|
|
78
83
|
const requestKey = `size${url}`;
|
|
79
84
|
const result = this.resourcesRegistryCache.sizeCache.get(url);
|
|
@@ -89,7 +94,10 @@ class ResourcesInliner {
|
|
|
89
94
|
this.resourcesRegistryCache.sizeCache.set(url, size);
|
|
90
95
|
}
|
|
91
96
|
if (size < resourceInlineThreshold) {
|
|
92
|
-
this.scheduleFileLoad(resource, resourceInlineThreshold);
|
|
97
|
+
const promise = this.scheduleFileLoad(resource, resourceInlineThreshold);
|
|
98
|
+
if (waitForFileLoad) {
|
|
99
|
+
await promise;
|
|
100
|
+
}
|
|
93
101
|
}
|
|
94
102
|
}
|
|
95
103
|
catch (error) {
|
|
@@ -112,7 +120,9 @@ class ResourcesInliner {
|
|
|
112
120
|
this.log = logger('resources-inliner');
|
|
113
121
|
}
|
|
114
122
|
getFilesCache(url) {
|
|
115
|
-
if (url.startsWith(ASSETS_PREFIX)
|
|
123
|
+
if (url.startsWith(ASSETS_PREFIX) ||
|
|
124
|
+
// reverse logic for `static` command in `getResourceUrl` method
|
|
125
|
+
(process.env.TRAMVAI_CLI_COMMAND === 'static' && url.startsWith(TRAMVAI_CLI_ASSETS_PREFIX))) {
|
|
116
126
|
// internal resources are resources generated by the current app itself
|
|
117
127
|
// these kind of resources are pretty static and won't be changed while app is running
|
|
118
128
|
// so we can cache it with bare Map and do not care about how to cleanup cache from outdated entries
|
|
@@ -209,6 +219,18 @@ class ResourcesInliner {
|
|
|
209
219
|
}
|
|
210
220
|
return result;
|
|
211
221
|
}
|
|
222
|
+
async prefetchResource(resource) {
|
|
223
|
+
const url = getResourceUrl(resource);
|
|
224
|
+
const resourceInlineThreshold = this.resourceInlineThreshold.threshold;
|
|
225
|
+
if (isUndefined__default["default"](url) ||
|
|
226
|
+
isUndefined__default["default"](resourceInlineThreshold) ||
|
|
227
|
+
this.resourcesRegistryCache.disabledUrlsCache.has(url)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (!this.resourcesRegistryCache.sizeCache.has(url)) {
|
|
231
|
+
await this.scheduleFileSizeLoad(resource, resourceInlineThreshold, true);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
212
234
|
}
|
|
213
235
|
|
|
214
236
|
exports.ResourcesInliner = ResourcesInliner;
|
|
@@ -23,6 +23,12 @@ class ResourcesRegistry {
|
|
|
23
23
|
}, [])
|
|
24
24
|
.filter((resource) => this.resourceInliner.shouldAddResource(resource));
|
|
25
25
|
}
|
|
26
|
+
prefetchInlinePageResources() {
|
|
27
|
+
const promises = Array.from(this.resources.values()).map((resource) => {
|
|
28
|
+
return this.resourceInliner.prefetchResource(resource);
|
|
29
|
+
});
|
|
30
|
+
return Promise.all(promises);
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
export { ResourcesRegistry };
|
|
@@ -31,6 +31,12 @@ class ResourcesRegistry {
|
|
|
31
31
|
}, [])
|
|
32
32
|
.filter((resource) => this.resourceInliner.shouldAddResource(resource));
|
|
33
33
|
}
|
|
34
|
+
prefetchInlinePageResources() {
|
|
35
|
+
const promises = Array.from(this.resources.values()).map((resource) => {
|
|
36
|
+
return this.resourceInliner.prefetchResource(resource);
|
|
37
|
+
});
|
|
38
|
+
return Promise.all(promises);
|
|
39
|
+
}
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
exports.ResourcesRegistry = ResourcesRegistry;
|
|
@@ -45,6 +45,9 @@ class PageBuilder {
|
|
|
45
45
|
this.log.warn({ event: 'render-flow-after-error', callback, error });
|
|
46
46
|
})));
|
|
47
47
|
this.dehydrateState();
|
|
48
|
+
if (process.env.TRAMVAI_CLI_COMMAND === 'static') {
|
|
49
|
+
await this.resourcesRegistry.prefetchInlinePageResources();
|
|
50
|
+
}
|
|
48
51
|
this.preloadBlock();
|
|
49
52
|
return this.generateHtml();
|
|
50
53
|
}
|
|
@@ -53,6 +53,9 @@ class PageBuilder {
|
|
|
53
53
|
this.log.warn({ event: 'render-flow-after-error', callback, error });
|
|
54
54
|
})));
|
|
55
55
|
this.dehydrateState();
|
|
56
|
+
if (process.env.TRAMVAI_CLI_COMMAND === 'static') {
|
|
57
|
+
await this.resourcesRegistry.prefetchInlinePageResources();
|
|
58
|
+
}
|
|
56
59
|
this.preloadBlock();
|
|
57
60
|
return this.generateHtml();
|
|
58
61
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-render",
|
|
3
|
-
"version": "2.94.
|
|
3
|
+
"version": "2.94.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"browser": "lib/browser.js",
|
|
6
6
|
"main": "lib/server.js",
|
|
@@ -26,14 +26,14 @@
|
|
|
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.94.
|
|
31
|
-
"@tramvai/module-page-render-mode": "2.94.
|
|
32
|
-
"@tramvai/module-router": "2.94.
|
|
33
|
-
"@tramvai/react": "2.94.
|
|
29
|
+
"@tinkoff/user-agent": "0.4.246",
|
|
30
|
+
"@tramvai/module-client-hints": "2.94.9",
|
|
31
|
+
"@tramvai/module-page-render-mode": "2.94.9",
|
|
32
|
+
"@tramvai/module-router": "2.94.9",
|
|
33
|
+
"@tramvai/react": "2.94.9",
|
|
34
34
|
"@tramvai/safe-strings": "0.5.8",
|
|
35
|
-
"@tramvai/tokens-render": "2.94.
|
|
36
|
-
"@tramvai/experiments": "2.94.
|
|
35
|
+
"@tramvai/tokens-render": "2.94.9",
|
|
36
|
+
"@tramvai/experiments": "2.94.9",
|
|
37
37
|
"@types/loadable__server": "^5.12.6",
|
|
38
38
|
"node-fetch": "^2.6.1"
|
|
39
39
|
},
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"@tinkoff/dippy": "0.8.15",
|
|
42
42
|
"@tinkoff/utils": "^2.1.2",
|
|
43
43
|
"@tinkoff/react-hooks": "0.1.6",
|
|
44
|
-
"@tramvai/cli": "2.94.
|
|
45
|
-
"@tramvai/core": "2.94.
|
|
46
|
-
"@tramvai/module-common": "2.94.
|
|
47
|
-
"@tramvai/state": "2.94.
|
|
48
|
-
"@tramvai/test-helpers": "2.94.
|
|
49
|
-
"@tramvai/tokens-common": "2.94.
|
|
50
|
-
"@tramvai/tokens-router": "2.94.
|
|
51
|
-
"@tramvai/tokens-server-private": "2.94.
|
|
44
|
+
"@tramvai/cli": "2.94.9",
|
|
45
|
+
"@tramvai/core": "2.94.9",
|
|
46
|
+
"@tramvai/module-common": "2.94.9",
|
|
47
|
+
"@tramvai/state": "2.94.9",
|
|
48
|
+
"@tramvai/test-helpers": "2.94.9",
|
|
49
|
+
"@tramvai/tokens-common": "2.94.9",
|
|
50
|
+
"@tramvai/tokens-router": "2.94.9",
|
|
51
|
+
"@tramvai/tokens-server-private": "2.94.9",
|
|
52
52
|
"express": "^4.17.1",
|
|
53
53
|
"prop-types": "^15.6.2",
|
|
54
54
|
"react": ">=16.14.0",
|
package/tests.js
CHANGED
|
@@ -51,11 +51,18 @@ class ResourcesRegistry {
|
|
|
51
51
|
}, [])
|
|
52
52
|
.filter((resource) => this.resourceInliner.shouldAddResource(resource));
|
|
53
53
|
}
|
|
54
|
+
prefetchInlinePageResources() {
|
|
55
|
+
const promises = Array.from(this.resources.values()).map((resource) => {
|
|
56
|
+
return this.resourceInliner.prefetchResource(resource);
|
|
57
|
+
});
|
|
58
|
+
return Promise.all(promises);
|
|
59
|
+
}
|
|
54
60
|
}
|
|
55
61
|
|
|
62
|
+
const TRAMVAI_CLI_ASSETS_PREFIX = `${process.env.TRAMVAI_CLI_ASSETS_PREFIX}`;
|
|
56
63
|
process.env.NODE_ENV === 'development' &&
|
|
57
64
|
(process.env.ASSETS_PREFIX === 'static' || !process.env.ASSETS_PREFIX)
|
|
58
|
-
?
|
|
65
|
+
? TRAMVAI_CLI_ASSETS_PREFIX
|
|
59
66
|
: process.env.ASSETS_PREFIX;
|
|
60
67
|
|
|
61
68
|
/**
|
|
@@ -171,6 +178,7 @@ const testPageResources = (options) => {
|
|
|
171
178
|
inlineResource() {
|
|
172
179
|
return [];
|
|
173
180
|
},
|
|
181
|
+
async prefetchResource() { },
|
|
174
182
|
},
|
|
175
183
|
}),
|
|
176
184
|
],
|