@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 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 !== 'false' && typeof hydrateRoot === 'function') {
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/lib/createToken/createToken").BaseTokenInterface<ResourcesInlinerType>;
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/lib/createToken/createToken").BaseTokenInterface<ResourcesRegistryCache>;
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
- constructor({ renderSlots, pageService, resourcesRegistry, context, reactRender, htmlPageSchema, polyfillCondition, htmlAttrs, modern, }: {
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({ event: 'page-render-error', error, requestInfo });
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({ event: 'page-render-error', error, requestInfo });
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/lib/createToken/createToken").MultiTokenInterface<import("@tramvai/core").Command>) => Promise<any[]>;
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.7.1",
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.4.24",
25
- "@tinkoff/layout-factory": "0.2.31",
26
- "@tinkoff/url": "0.7.39",
27
- "@tinkoff/user-agent": "0.4.24",
28
- "@tramvai/module-client-hints": "2.7.1",
29
- "@tramvai/module-router": "2.7.1",
30
- "@tramvai/react": "2.7.1",
31
- "@tramvai/safe-strings": "0.4.5",
32
- "@tramvai/tokens-render": "2.7.1",
33
- "@tramvai/experiments": "2.7.1",
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.7.44",
38
+ "@tinkoff/dippy": "0.8.2",
39
39
  "@tinkoff/utils": "^2.1.2",
40
- "@tinkoff/react-hooks": "0.0.27",
41
- "@tramvai/cli": "2.7.1",
42
- "@tramvai/core": "2.7.1",
43
- "@tramvai/module-common": "2.7.1",
44
- "@tramvai/state": "2.7.1",
45
- "@tramvai/test-helpers": "2.7.1",
46
- "@tramvai/tokens-common": "2.7.1",
47
- "@tramvai/tokens-router": "2.7.1",
48
- "@tramvai/tokens-server-private": "2.7.1",
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",