@tramvai/module-render 2.7.1 → 2.20.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.js +1 -1
- package/lib/resourcesInliner/tokens.d.ts +2 -2
- package/lib/server/PageBuilder.d.ts +5 -1
- package/lib/server.es.js +17 -3
- package/lib/server.js +16 -2
- package/lib/test/unit/resources.d.ts +1 -1
- package/package.json +21 -21
package/lib/browser.js
CHANGED
|
@@ -83,7 +83,7 @@ const ExecuteRenderCallback = ({ children, callback, }) => {
|
|
|
83
83
|
return children;
|
|
84
84
|
};
|
|
85
85
|
const renderer = ({ element, container, callback, log }) => {
|
|
86
|
-
if (process.env.__TRAMVAI_CONCURRENT_FEATURES
|
|
86
|
+
if (process.env.__TRAMVAI_CONCURRENT_FEATURES && typeof hydrateRoot === 'function') {
|
|
87
87
|
const wrappedElement = createElement(ExecuteRenderCallback, { callback }, element);
|
|
88
88
|
return hydrateRoot(container, wrappedElement, {
|
|
89
89
|
onRecoverableError: (error, errorInfo) => {
|
|
@@ -5,7 +5,7 @@ import type { ResourcesInlinerType } from './resourcesInliner';
|
|
|
5
5
|
* Инлайнер ресурсов - используется на сервере для регистрации файлов, которые должны быть вставлены
|
|
6
6
|
* в итоговую html-страницу в виде ссылки на файл или заинлайнеными полностью
|
|
7
7
|
*/
|
|
8
|
-
export declare const RESOURCE_INLINER: import("@tinkoff/dippy
|
|
8
|
+
export declare const RESOURCE_INLINER: import("@tinkoff/dippy").BaseTokenInterface<ResourcesInlinerType>;
|
|
9
9
|
export declare type ResourcesRegistryCache = {
|
|
10
10
|
filesCache: Cache;
|
|
11
11
|
sizeCache: Cache;
|
|
@@ -15,4 +15,4 @@ export declare type ResourcesRegistryCache = {
|
|
|
15
15
|
* @description
|
|
16
16
|
* Кэш загруженных ресурсов.
|
|
17
17
|
*/
|
|
18
|
-
export declare const RESOURCES_REGISTRY_CACHE: import("@tinkoff/dippy
|
|
18
|
+
export declare const RESOURCES_REGISTRY_CACHE: import("@tinkoff/dippy").BaseTokenInterface<ResourcesRegistryCache>;
|
|
@@ -9,7 +9,9 @@ export declare class PageBuilder {
|
|
|
9
9
|
private htmlAttrs;
|
|
10
10
|
private polyfillCondition;
|
|
11
11
|
private modern;
|
|
12
|
-
|
|
12
|
+
private renderFlowAfter;
|
|
13
|
+
private log;
|
|
14
|
+
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, }: {
|
|
13
15
|
renderSlots: any;
|
|
14
16
|
pageService: any;
|
|
15
17
|
resourcesRegistry: any;
|
|
@@ -19,6 +21,8 @@ export declare class PageBuilder {
|
|
|
19
21
|
polyfillCondition: any;
|
|
20
22
|
htmlAttrs: any;
|
|
21
23
|
modern: any;
|
|
24
|
+
renderFlowAfter: any;
|
|
25
|
+
logger: any;
|
|
22
26
|
});
|
|
23
27
|
flow(): Promise<string>;
|
|
24
28
|
dehydrateState(): void;
|
package/lib/server.es.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Module, provide, commandLineListTokens, DI_TOKEN } from '@tramvai/core'
|
|
|
5
5
|
import { COMBINE_REDUCERS, CREATE_CACHE_TOKEN, LOGGER_TOKEN, REQUEST_MANAGER_TOKEN, RESPONSE_MANAGER_TOKEN, CONTEXT_TOKEN } from '@tramvai/tokens-common';
|
|
6
6
|
import { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
7
7
|
import { ClientHintsModule, USER_AGENT_TOKEN } from '@tramvai/module-client-hints';
|
|
8
|
-
import { ResourceType, ResourceSlot, DEFAULT_LAYOUT_COMPONENT, LAYOUT_OPTIONS, DEFAULT_FOOTER_COMPONENT, DEFAULT_HEADER_COMPONENT, TRAMVAI_RENDER_MODE, RESOURCES_REGISTRY, RESOURCE_INLINE_OPTIONS, RENDER_SLOTS, POLYFILL_CONDITION, HTML_ATTRS, CUSTOM_RENDER, EXTEND_RENDER } from '@tramvai/tokens-render';
|
|
8
|
+
import { ResourceType, ResourceSlot, DEFAULT_LAYOUT_COMPONENT, LAYOUT_OPTIONS, DEFAULT_FOOTER_COMPONENT, DEFAULT_HEADER_COMPONENT, TRAMVAI_RENDER_MODE, RESOURCES_REGISTRY, RESOURCE_INLINE_OPTIONS, RENDER_SLOTS, POLYFILL_CONDITION, HTML_ATTRS, RENDER_FLOW_AFTER_TOKEN, CUSTOM_RENDER, EXTEND_RENDER } from '@tramvai/tokens-render';
|
|
9
9
|
export * from '@tramvai/tokens-render';
|
|
10
10
|
import { createToken, Scope } from '@tinkoff/dippy';
|
|
11
11
|
import { WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN } from '@tramvai/tokens-server-private';
|
|
@@ -537,13 +537,14 @@ const formatAttributes = (htmlAttrs, target) => {
|
|
|
537
537
|
return attrsString.trim();
|
|
538
538
|
};
|
|
539
539
|
|
|
540
|
+
/* eslint-disable sort-class-members/sort-class-members */
|
|
540
541
|
const mapResourcesToSlots = (resources) => resources.reduce((acc, resource) => {
|
|
541
542
|
const { slot } = resource;
|
|
542
543
|
acc[slot] = Array.isArray(acc[slot]) ? [...acc[slot], resource] : [resource];
|
|
543
544
|
return acc;
|
|
544
545
|
}, {});
|
|
545
546
|
class PageBuilder {
|
|
546
|
-
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, }) {
|
|
547
|
+
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, }) {
|
|
547
548
|
this.htmlAttrs = htmlAttrs;
|
|
548
549
|
this.renderSlots = flatten(renderSlots || []);
|
|
549
550
|
this.pageService = pageService;
|
|
@@ -553,12 +554,17 @@ class PageBuilder {
|
|
|
553
554
|
this.htmlPageSchema = htmlPageSchema;
|
|
554
555
|
this.polyfillCondition = polyfillCondition;
|
|
555
556
|
this.modern = modern;
|
|
557
|
+
this.renderFlowAfter = renderFlowAfter || [];
|
|
558
|
+
this.log = logger('page-builder');
|
|
556
559
|
}
|
|
557
560
|
async flow() {
|
|
558
561
|
const stats = await fetchWebpackStats({ modern: this.modern });
|
|
559
562
|
const extractor = new ChunkExtractor({ stats, entrypoints: [] });
|
|
560
563
|
// самым первым рендерим приложение, так как нужно вытащить информацию о используемых данных компонентами
|
|
561
564
|
await this.renderApp(extractor);
|
|
565
|
+
await Promise.all(this.renderFlowAfter.map((callback) => callback().catch((error) => {
|
|
566
|
+
this.log.warn({ event: 'render-flow-after-error', callback, error });
|
|
567
|
+
})));
|
|
562
568
|
this.dehydrateState();
|
|
563
569
|
// загружаем информацию и зависимость для текущего бандла и странице
|
|
564
570
|
await this.fetchChunksInfo(extractor);
|
|
@@ -604,6 +610,7 @@ class PageBuilder {
|
|
|
604
610
|
});
|
|
605
611
|
}
|
|
606
612
|
}
|
|
613
|
+
/* eslint-enable sort-class-members/sort-class-members */
|
|
607
614
|
|
|
608
615
|
const { REACT_RENDER, HEAD_CORE_SCRIPTS, HEAD_DYNAMIC_SCRIPTS, HEAD_META, HEAD_POLYFILLS, HEAD_CORE_STYLES, HEAD_PERFORMANCE, HEAD_ANALYTICS, BODY_START, BODY_END, HEAD_ICONS, BODY_TAIL_ANALYTICS, BODY_TAIL, } = ResourceSlot;
|
|
609
616
|
const htmlPageSchemaFactory = ({ htmlAttrs, }) => {
|
|
@@ -822,7 +829,12 @@ RenderModule = RenderModule_1 = __decorate([
|
|
|
822
829
|
requestId: requestManager.getHeader('x-request-id'),
|
|
823
830
|
url: requestManager.getUrl(),
|
|
824
831
|
};
|
|
825
|
-
log.error({
|
|
832
|
+
log.error({
|
|
833
|
+
event: 'send-server-error',
|
|
834
|
+
message: 'Page render error, switch to fallback',
|
|
835
|
+
error,
|
|
836
|
+
requestInfo,
|
|
837
|
+
});
|
|
826
838
|
// Assuming that there was an error when rendering the page, try to render again with ErrorBoundary
|
|
827
839
|
context.dispatch(setPageErrorEvent(error));
|
|
828
840
|
html = await htmlBuilder.flow();
|
|
@@ -862,6 +874,8 @@ RenderModule = RenderModule_1 = __decorate([
|
|
|
862
874
|
polyfillCondition: POLYFILL_CONDITION,
|
|
863
875
|
htmlAttrs: HTML_ATTRS,
|
|
864
876
|
modern: 'modernSatisfies',
|
|
877
|
+
renderFlowAfter: { token: RENDER_FLOW_AFTER_TOKEN, optional: true },
|
|
878
|
+
logger: LOGGER_TOKEN,
|
|
865
879
|
},
|
|
866
880
|
}),
|
|
867
881
|
provide({
|
package/lib/server.js
CHANGED
|
@@ -573,13 +573,14 @@ const formatAttributes = (htmlAttrs, target) => {
|
|
|
573
573
|
return attrsString.trim();
|
|
574
574
|
};
|
|
575
575
|
|
|
576
|
+
/* eslint-disable sort-class-members/sort-class-members */
|
|
576
577
|
const mapResourcesToSlots = (resources) => resources.reduce((acc, resource) => {
|
|
577
578
|
const { slot } = resource;
|
|
578
579
|
acc[slot] = Array.isArray(acc[slot]) ? [...acc[slot], resource] : [resource];
|
|
579
580
|
return acc;
|
|
580
581
|
}, {});
|
|
581
582
|
class PageBuilder {
|
|
582
|
-
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, }) {
|
|
583
|
+
constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, renderFlowAfter, logger, }) {
|
|
583
584
|
this.htmlAttrs = htmlAttrs;
|
|
584
585
|
this.renderSlots = flatten__default["default"](renderSlots || []);
|
|
585
586
|
this.pageService = pageService;
|
|
@@ -589,12 +590,17 @@ class PageBuilder {
|
|
|
589
590
|
this.htmlPageSchema = htmlPageSchema;
|
|
590
591
|
this.polyfillCondition = polyfillCondition;
|
|
591
592
|
this.modern = modern;
|
|
593
|
+
this.renderFlowAfter = renderFlowAfter || [];
|
|
594
|
+
this.log = logger('page-builder');
|
|
592
595
|
}
|
|
593
596
|
async flow() {
|
|
594
597
|
const stats = await fetchWebpackStats({ modern: this.modern });
|
|
595
598
|
const extractor = new server.ChunkExtractor({ stats, entrypoints: [] });
|
|
596
599
|
// самым первым рендерим приложение, так как нужно вытащить информацию о используемых данных компонентами
|
|
597
600
|
await this.renderApp(extractor);
|
|
601
|
+
await Promise.all(this.renderFlowAfter.map((callback) => callback().catch((error) => {
|
|
602
|
+
this.log.warn({ event: 'render-flow-after-error', callback, error });
|
|
603
|
+
})));
|
|
598
604
|
this.dehydrateState();
|
|
599
605
|
// загружаем информацию и зависимость для текущего бандла и странице
|
|
600
606
|
await this.fetchChunksInfo(extractor);
|
|
@@ -640,6 +646,7 @@ class PageBuilder {
|
|
|
640
646
|
});
|
|
641
647
|
}
|
|
642
648
|
}
|
|
649
|
+
/* eslint-enable sort-class-members/sort-class-members */
|
|
643
650
|
|
|
644
651
|
const { REACT_RENDER, HEAD_CORE_SCRIPTS, HEAD_DYNAMIC_SCRIPTS, HEAD_META, HEAD_POLYFILLS, HEAD_CORE_STYLES, HEAD_PERFORMANCE, HEAD_ANALYTICS, BODY_START, BODY_END, HEAD_ICONS, BODY_TAIL_ANALYTICS, BODY_TAIL, } = tokensRender.ResourceSlot;
|
|
645
652
|
const htmlPageSchemaFactory = ({ htmlAttrs, }) => {
|
|
@@ -858,7 +865,12 @@ exports.RenderModule = RenderModule_1 = tslib.__decorate([
|
|
|
858
865
|
requestId: requestManager.getHeader('x-request-id'),
|
|
859
866
|
url: requestManager.getUrl(),
|
|
860
867
|
};
|
|
861
|
-
log.error({
|
|
868
|
+
log.error({
|
|
869
|
+
event: 'send-server-error',
|
|
870
|
+
message: 'Page render error, switch to fallback',
|
|
871
|
+
error,
|
|
872
|
+
requestInfo,
|
|
873
|
+
});
|
|
862
874
|
// Assuming that there was an error when rendering the page, try to render again with ErrorBoundary
|
|
863
875
|
context.dispatch(setPageErrorEvent(error));
|
|
864
876
|
html = await htmlBuilder.flow();
|
|
@@ -898,6 +910,8 @@ exports.RenderModule = RenderModule_1 = tslib.__decorate([
|
|
|
898
910
|
polyfillCondition: tokensRender.POLYFILL_CONDITION,
|
|
899
911
|
htmlAttrs: tokensRender.HTML_ATTRS,
|
|
900
912
|
modern: 'modernSatisfies',
|
|
913
|
+
renderFlowAfter: { token: tokensRender.RENDER_FLOW_AFTER_TOKEN, optional: true },
|
|
914
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
901
915
|
},
|
|
902
916
|
}),
|
|
903
917
|
core.provide({
|
|
@@ -8,6 +8,6 @@ export declare const testPageResources: (options: Options) => {
|
|
|
8
8
|
application: string;
|
|
9
9
|
};
|
|
10
10
|
di: import("@tinkoff/dippy").Container;
|
|
11
|
-
runLine: (line: import("@tinkoff/dippy
|
|
11
|
+
runLine: (line: import("@tinkoff/dippy").MultiTokenInterface<import("@tramvai/core").Command>) => Promise<any[]>;
|
|
12
12
|
};
|
|
13
13
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-render",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"browser": "lib/browser.js",
|
|
6
6
|
"main": "lib/server.js",
|
|
@@ -21,31 +21,31 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@loadable/server": "^5.15.0",
|
|
24
|
-
"@tinkoff/htmlpagebuilder": "0.
|
|
25
|
-
"@tinkoff/layout-factory": "0.2
|
|
26
|
-
"@tinkoff/url": "0.
|
|
27
|
-
"@tinkoff/user-agent": "0.4.
|
|
28
|
-
"@tramvai/module-client-hints": "2.
|
|
29
|
-
"@tramvai/module-router": "2.
|
|
30
|
-
"@tramvai/react": "2.
|
|
31
|
-
"@tramvai/safe-strings": "0.
|
|
32
|
-
"@tramvai/tokens-render": "2.
|
|
33
|
-
"@tramvai/experiments": "2.
|
|
24
|
+
"@tinkoff/htmlpagebuilder": "0.5.2",
|
|
25
|
+
"@tinkoff/layout-factory": "0.3.2",
|
|
26
|
+
"@tinkoff/url": "0.8.2",
|
|
27
|
+
"@tinkoff/user-agent": "0.4.51",
|
|
28
|
+
"@tramvai/module-client-hints": "2.20.0",
|
|
29
|
+
"@tramvai/module-router": "2.20.0",
|
|
30
|
+
"@tramvai/react": "2.20.0",
|
|
31
|
+
"@tramvai/safe-strings": "0.5.2",
|
|
32
|
+
"@tramvai/tokens-render": "2.20.0",
|
|
33
|
+
"@tramvai/experiments": "2.20.0",
|
|
34
34
|
"@types/loadable__server": "^5.12.6",
|
|
35
35
|
"node-fetch": "^2.6.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@tinkoff/dippy": "0.
|
|
38
|
+
"@tinkoff/dippy": "0.8.2",
|
|
39
39
|
"@tinkoff/utils": "^2.1.2",
|
|
40
|
-
"@tinkoff/react-hooks": "0.
|
|
41
|
-
"@tramvai/cli": "2.
|
|
42
|
-
"@tramvai/core": "2.
|
|
43
|
-
"@tramvai/module-common": "2.
|
|
44
|
-
"@tramvai/state": "2.
|
|
45
|
-
"@tramvai/test-helpers": "2.
|
|
46
|
-
"@tramvai/tokens-common": "2.
|
|
47
|
-
"@tramvai/tokens-router": "2.
|
|
48
|
-
"@tramvai/tokens-server-private": "2.
|
|
40
|
+
"@tinkoff/react-hooks": "0.1.2",
|
|
41
|
+
"@tramvai/cli": "2.20.0",
|
|
42
|
+
"@tramvai/core": "2.20.0",
|
|
43
|
+
"@tramvai/module-common": "2.20.0",
|
|
44
|
+
"@tramvai/state": "2.20.0",
|
|
45
|
+
"@tramvai/test-helpers": "2.20.0",
|
|
46
|
+
"@tramvai/tokens-common": "2.20.0",
|
|
47
|
+
"@tramvai/tokens-router": "2.20.0",
|
|
48
|
+
"@tramvai/tokens-server-private": "2.20.0",
|
|
49
49
|
"express": "^4.17.1",
|
|
50
50
|
"prop-types": "^15.6.2",
|
|
51
51
|
"react": ">=16.14.0",
|