@dr.pogodin/react-utils 1.46.2 → 1.47.0-alpha.11
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/babel.config.js +1 -0
- package/babel.libweb.config.js +16 -0
- package/babel.module.config.js +11 -0
- package/bin/build.js +21 -11
- package/bin/setup.js +11 -9
- package/build/development/client/getInj.js +57 -44
- package/build/development/client/getInj.js.map +1 -1
- package/build/development/client/index.js +15 -21
- package/build/development/client/index.js.map +1 -1
- package/build/development/client/init.js +2 -6
- package/build/development/client/init.js.map +1 -1
- package/build/development/index.js +3 -177
- package/build/development/index.js.map +1 -1
- package/build/development/server/Cache.js +1 -8
- package/build/development/server/Cache.js.map +1 -1
- package/build/development/server/index.js +22 -45
- package/build/development/server/index.js.map +1 -1
- package/build/development/server/renderer.js +84 -86
- package/build/development/server/renderer.js.map +1 -1
- package/build/development/server/server.js +58 -60
- package/build/development/server/server.js.map +1 -1
- package/build/development/server/utils/errors.js +8 -31
- package/build/development/server/utils/errors.js.map +1 -1
- package/build/development/server/utils/index.js +2 -9
- package/build/development/server/utils/index.js.map +1 -1
- package/build/development/shared/components/Button/index.js +15 -22
- package/build/development/shared/components/Button/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +14 -21
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/GenericLink/index.js +9 -11
- package/build/development/shared/components/GenericLink/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +21 -27
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/Link.js +6 -13
- package/build/development/shared/components/Link.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +24 -28
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/NavLink.js +6 -13
- package/build/development/shared/components/NavLink.js.map +1 -1
- package/build/development/shared/components/PageLayout/index.js +13 -20
- package/build/development/shared/components/PageLayout/index.js.map +1 -1
- package/build/development/shared/components/TextArea/index.js +28 -31
- package/build/development/shared/components/TextArea/index.js.map +1 -1
- package/build/development/shared/components/Throbber/index.js +13 -20
- package/build/development/shared/components/Throbber/index.js.map +1 -1
- package/build/development/shared/components/WithTooltip/Tooltip.js +13 -18
- package/build/development/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/development/shared/components/WithTooltip/index.js +23 -30
- package/build/development/shared/components/WithTooltip/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +19 -26
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/index.js +16 -130
- package/build/development/shared/components/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js +19 -20
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/index.js +35 -39
- package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/NativeDropdown/index.js +31 -31
- package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/Switch/index.js +19 -24
- package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/development/shared/components/selectors/common.js +1 -7
- package/build/development/shared/components/selectors/common.js.map +1 -1
- package/build/development/shared/components/selectors/index.js +3 -27
- package/build/development/shared/components/selectors/index.js.map +1 -1
- package/build/development/shared/utils/config.js +40 -21
- package/build/development/shared/utils/config.js.map +1 -1
- package/build/development/shared/utils/globalState.js +3 -8
- package/build/development/shared/utils/globalState.js.map +1 -1
- package/build/development/shared/utils/index.js +12 -89
- package/build/development/shared/utils/index.js.map +1 -1
- package/build/development/shared/utils/isomorphy/buildInfo.js +2 -9
- package/build/development/shared/utils/isomorphy/buildInfo.js.map +1 -1
- package/build/development/shared/utils/isomorphy/environment-check.js +2 -8
- package/build/development/shared/utils/isomorphy/environment-check.js.map +1 -1
- package/build/development/shared/utils/isomorphy/index.js +7 -32
- package/build/development/shared/utils/isomorphy/index.js.map +1 -1
- package/build/development/shared/utils/jest/E2eSsrEnv.js +34 -37
- package/build/development/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/development/shared/utils/jest/global.js +1 -7
- package/build/development/shared/utils/jest/global.js.map +1 -1
- package/build/development/shared/utils/jest/index.js +20 -44
- package/build/development/shared/utils/jest/index.js.map +1 -1
- package/build/development/shared/utils/splitComponent.js +54 -45
- package/build/development/shared/utils/splitComponent.js.map +1 -1
- package/build/development/shared/utils/time.js +22 -31
- package/build/development/shared/utils/time.js.map +1 -1
- package/build/development/shared/utils/webpack.js +17 -16
- package/build/development/shared/utils/webpack.js.map +1 -1
- package/build/production/client/getInj.js +13 -11
- package/build/production/client/getInj.js.map +1 -1
- package/build/production/client/index.js +3 -3
- package/build/production/client/index.js.map +1 -1
- package/build/production/client/init.js +2 -2
- package/build/production/client/init.js.map +1 -1
- package/build/production/index.js +2 -3
- package/build/production/index.js.map +1 -1
- package/build/production/server/Cache.js +3 -3
- package/build/production/server/Cache.js.map +1 -1
- package/build/production/server/index.js +8 -8
- package/build/production/server/index.js.map +1 -1
- package/build/production/server/renderer.js +24 -25
- package/build/production/server/renderer.js.map +1 -1
- package/build/production/server/server.js +9 -11
- package/build/production/server/server.js.map +1 -1
- package/build/production/server/utils/errors.js +9 -9
- package/build/production/server/utils/errors.js.map +1 -1
- package/build/production/server/utils/index.js +2 -1
- package/build/production/server/utils/index.js.map +1 -1
- package/build/production/shared/components/Button/index.js +4 -4
- package/build/production/shared/components/Button/index.js.map +1 -1
- package/build/production/shared/components/Checkbox/index.js +1 -1
- package/build/production/shared/components/Checkbox/index.js.map +1 -1
- package/build/production/shared/components/GenericLink/index.js +4 -4
- package/build/production/shared/components/GenericLink/index.js.map +1 -1
- package/build/production/shared/components/Input/index.js +5 -5
- package/build/production/shared/components/Input/index.js.map +1 -1
- package/build/production/shared/components/Link.js +3 -3
- package/build/production/shared/components/Link.js.map +1 -1
- package/build/production/shared/components/Modal/index.js +7 -7
- package/build/production/shared/components/Modal/index.js.map +1 -1
- package/build/production/shared/components/NavLink.js +2 -2
- package/build/production/shared/components/NavLink.js.map +1 -1
- package/build/production/shared/components/PageLayout/index.js +2 -2
- package/build/production/shared/components/PageLayout/index.js.map +1 -1
- package/build/production/shared/components/TextArea/index.js +5 -5
- package/build/production/shared/components/TextArea/index.js.map +1 -1
- package/build/production/shared/components/Throbber/index.js +2 -2
- package/build/production/shared/components/Throbber/index.js.map +1 -1
- package/build/production/shared/components/WithTooltip/Tooltip.js +4 -4
- package/build/production/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/production/shared/components/WithTooltip/index.js +4 -4
- package/build/production/shared/components/WithTooltip/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +4 -4
- package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/production/shared/components/index.js +3 -1
- package/build/production/shared/components/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js +2 -2
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/index.js +2 -2
- package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/NativeDropdown/index.js +4 -4
- package/build/production/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/Switch/index.js +1 -1
- package/build/production/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/production/shared/components/selectors/common.js +2 -2
- package/build/production/shared/components/selectors/common.js.map +1 -1
- package/build/production/shared/components/selectors/index.js +1 -1
- package/build/production/shared/components/selectors/index.js.map +1 -1
- package/build/production/shared/utils/config.js +8 -6
- package/build/production/shared/utils/config.js.map +1 -1
- package/build/production/shared/utils/globalState.js +2 -2
- package/build/production/shared/utils/globalState.js.map +1 -1
- package/build/production/shared/utils/index.js +1 -1
- package/build/production/shared/utils/index.js.map +1 -1
- package/build/production/shared/utils/isomorphy/buildInfo.js +3 -3
- package/build/production/shared/utils/isomorphy/buildInfo.js.map +1 -1
- package/build/production/shared/utils/isomorphy/environment-check.js +3 -3
- package/build/production/shared/utils/isomorphy/environment-check.js.map +1 -1
- package/build/production/shared/utils/isomorphy/index.js +4 -4
- package/build/production/shared/utils/isomorphy/index.js.map +1 -1
- package/build/production/shared/utils/jest/E2eSsrEnv.js +16 -15
- package/build/production/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/production/shared/utils/jest/global.js +1 -1
- package/build/production/shared/utils/jest/global.js.map +1 -1
- package/build/production/shared/utils/jest/index.js +11 -11
- package/build/production/shared/utils/jest/index.js.map +1 -1
- package/build/production/shared/utils/splitComponent.js +11 -22
- package/build/production/shared/utils/splitComponent.js.map +1 -1
- package/build/production/shared/utils/time.js +3 -3
- package/build/production/shared/utils/time.js.map +1 -1
- package/build/production/shared/utils/webpack.js +6 -6
- package/build/production/shared/utils/webpack.js.map +1 -1
- package/build/types-code/client/getInj.d.ts +1 -2
- package/build/types-code/client/index.d.ts +1 -1
- package/build/types-code/index.d.ts +1 -7
- package/build/types-code/server/index.d.ts +6 -11
- package/build/types-code/server/utils/index.d.ts +1 -1
- package/build/types-code/shared/utils/config.d.ts +4 -2
- package/build/types-code/shared/utils/index.d.ts +2 -2
- package/build/types-code/shared/utils/splitComponent.d.ts +6 -4
- package/build/web/client/getInj.js +65 -0
- package/build/web/client/getInj.js.map +1 -0
- package/{src/client/index.tsx → build/web/client/index.js} +13 -24
- package/build/web/client/index.js.map +1 -0
- package/{src/client/init.ts → build/web/client/init.js} +9 -14
- package/build/web/client/init.js.map +1 -0
- package/build/web/index.js +11 -0
- package/build/web/index.js.map +1 -0
- package/{src/server/Cache.ts → build/web/server/Cache.js} +15 -22
- package/build/web/server/Cache.js.map +1 -0
- package/{src/server/index.ts → build/web/server/index.js} +32 -81
- package/build/web/server/index.js.map +1 -0
- package/{src/server/renderer.tsx → build/web/server/renderer.js} +188 -333
- package/build/web/server/renderer.js.map +1 -0
- package/{src/server/server.ts → build/web/server/server.js} +82 -182
- package/build/web/server/server.js.map +1 -0
- package/{src/server/utils/errors.ts → build/web/server/utils/errors.js} +6 -25
- package/build/web/server/utils/errors.js.map +1 -0
- package/build/web/server/utils/index.js +4 -0
- package/build/web/server/utils/index.js.map +1 -0
- package/build/web/shared/components/Button/index.js +90 -0
- package/build/web/shared/components/Button/index.js.map +1 -0
- package/build/web/shared/components/Checkbox/index.js +35 -0
- package/build/web/shared/components/Checkbox/index.js.map +1 -0
- package/{src/shared/components/GenericLink/index.tsx → build/web/shared/components/GenericLink/index.js} +44 -78
- package/build/web/shared/components/GenericLink/index.js.map +1 -0
- package/build/web/shared/components/Input/index.js +71 -0
- package/build/web/shared/components/Input/index.js.map +1 -0
- package/build/web/shared/components/Link.js +20 -0
- package/build/web/shared/components/Link.js.map +1 -0
- package/{src → build/web}/shared/components/Modal/base-theme.scss +1 -1
- package/build/web/shared/components/Modal/index.js +128 -0
- package/build/web/shared/components/Modal/index.js.map +1 -0
- package/build/web/shared/components/NavLink.js +13 -0
- package/build/web/shared/components/NavLink.js.map +1 -0
- package/{src → build/web}/shared/components/PageLayout/base-theme.scss +1 -1
- package/{src/shared/components/PageLayout/index.tsx → build/web/shared/components/PageLayout/index.js} +20 -33
- package/build/web/shared/components/PageLayout/index.js.map +1 -0
- package/build/web/shared/components/TextArea/index.js +106 -0
- package/build/web/shared/components/TextArea/index.js.map +1 -0
- package/build/web/shared/components/Throbber/index.js +26 -0
- package/build/web/shared/components/Throbber/index.js.map +1 -0
- package/{src/shared/components/WithTooltip/Tooltip.tsx → build/web/shared/components/WithTooltip/Tooltip.js} +61 -109
- package/build/web/shared/components/WithTooltip/Tooltip.js.map +1 -0
- package/build/web/shared/components/WithTooltip/index.js +117 -0
- package/build/web/shared/components/WithTooltip/index.js.map +1 -0
- package/{src/shared/components/YouTubeVideo/index.tsx → build/web/shared/components/YouTubeVideo/index.js} +23 -40
- package/build/web/shared/components/YouTubeVideo/index.js.map +1 -0
- package/build/web/shared/components/index.js +18 -0
- package/build/web/shared/components/index.js.map +1 -0
- package/build/web/shared/components/selectors/CustomDropdown/Options/index.js +82 -0
- package/build/web/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -0
- package/{src/shared/components/selectors/CustomDropdown/index.tsx → build/web/shared/components/selectors/CustomDropdown/index.js} +56 -80
- package/build/web/shared/components/selectors/CustomDropdown/index.js.map +1 -0
- package/{src/shared/components/selectors/NativeDropdown/index.tsx → build/web/shared/components/selectors/NativeDropdown/index.js} +39 -44
- package/build/web/shared/components/selectors/NativeDropdown/index.js.map +1 -0
- package/build/web/shared/components/selectors/Switch/index.js +50 -0
- package/build/web/shared/components/selectors/Switch/index.js.map +1 -0
- package/build/web/shared/components/selectors/common.js +12 -0
- package/build/web/shared/components/selectors/common.js.map +1 -0
- package/build/web/shared/components/selectors/index.js +4 -0
- package/build/web/shared/components/selectors/index.js.map +1 -0
- package/build/web/shared/utils/config.js +45 -0
- package/build/web/shared/utils/config.js.map +1 -0
- package/build/web/shared/utils/globalState.js +15 -0
- package/build/web/shared/utils/globalState.js.map +1 -0
- package/build/web/shared/utils/index.js +13 -0
- package/build/web/shared/utils/index.js.map +1 -0
- package/{src/shared/utils/isomorphy/buildInfo.ts → build/web/shared/utils/isomorphy/buildInfo.js} +4 -10
- package/build/web/shared/utils/isomorphy/buildInfo.js.map +1 -0
- package/build/web/shared/utils/isomorphy/environment-check.js +17 -0
- package/build/web/shared/utils/isomorphy/environment-check.js.map +1 -0
- package/{src/shared/utils/isomorphy/index.ts → build/web/shared/utils/isomorphy/index.js} +6 -6
- package/build/web/shared/utils/isomorphy/index.js.map +1 -0
- package/{src/shared/utils/jest/E2eSsrEnv.ts → build/web/shared/utils/jest/E2eSsrEnv.js} +73 -140
- package/build/web/shared/utils/jest/E2eSsrEnv.js.map +1 -0
- package/build/web/shared/utils/jest/global.js +4 -0
- package/build/web/shared/utils/jest/global.js.map +1 -0
- package/{src/shared/utils/jest/index.ts → build/web/shared/utils/jest/index.js} +33 -83
- package/build/web/shared/utils/jest/index.js.map +1 -0
- package/{src/shared/utils/splitComponent.tsx → build/web/shared/utils/splitComponent.js} +77 -124
- package/build/web/shared/utils/splitComponent.js.map +1 -0
- package/{src/shared/utils/time.ts → build/web/shared/utils/time.js} +21 -37
- package/build/web/shared/utils/time.js.map +1 -0
- package/build/web/shared/utils/webpack.js +67 -0
- package/build/web/shared/utils/webpack.js.map +1 -0
- package/config/babel/node-ssr.js +12 -3
- package/config/babel/webpack.js +6 -1
- package/config/jest/default.js +8 -2
- package/config/jest/setup.js +8 -1
- package/config/webpack/app-base.js +25 -14
- package/config/webpack/app-development.js +2 -2
- package/config/webpack/lib-base.js +1 -2
- package/package.json +41 -42
- package/types.d.ts +1 -6
- package/build/development/__chunk_groups__.json +0 -6
- package/build/development/style.css +0 -909
- package/build/development/web.bundle.js +0 -752
- package/build/production/__chunk_groups__.json +0 -6
- package/build/production/style.css +0 -2
- package/build/production/style.css.map +0 -1
- package/build/production/web.bundle.js +0 -3
- package/build/production/web.bundle.js.LICENSE.txt +0 -9
- package/build/production/web.bundle.js.map +0 -1
- package/dev-styles.js +0 -1
- package/node-entry.js +0 -15
- package/null.js +0 -1
- package/prod-styles.js +0 -1
- package/src/client/getInj.ts +0 -51
- package/src/index.ts +0 -73
- package/src/server/utils/index.ts +0 -3
- package/src/shared/components/Button/index.tsx +0 -130
- package/src/shared/components/Checkbox/index.tsx +0 -53
- package/src/shared/components/Input/index.tsx +0 -96
- package/src/shared/components/Link.tsx +0 -25
- package/src/shared/components/Modal/index.tsx +0 -177
- package/src/shared/components/NavLink.tsx +0 -18
- package/src/shared/components/TextArea/index.tsx +0 -139
- package/src/shared/components/Throbber/index.tsx +0 -28
- package/src/shared/components/WithTooltip/index.tsx +0 -186
- package/src/shared/components/index.ts +0 -20
- package/src/shared/components/selectors/CustomDropdown/Options/index.tsx +0 -124
- package/src/shared/components/selectors/Switch/index.tsx +0 -74
- package/src/shared/components/selectors/common.ts +0 -57
- package/src/shared/components/selectors/index.ts +0 -8
- package/src/shared/utils/config.ts +0 -28
- package/src/shared/utils/globalState.ts +0 -44
- package/src/shared/utils/index.ts +0 -45
- package/src/shared/utils/isomorphy/environment-check.ts +0 -18
- package/src/shared/utils/jest/global.ts +0 -17
- package/src/shared/utils/webpack.ts +0 -74
- /package/{src → build/web}/shared/components/Button/style.scss +0 -0
- /package/{src → build/web}/shared/components/Checkbox/theme.scss +0 -0
- /package/{src → build/web}/shared/components/GenericLink/style.scss +0 -0
- /package/{src → build/web}/shared/components/Input/theme.scss +0 -0
- /package/{src → build/web}/shared/components/Modal/styles.scss +0 -0
- /package/{src → build/web}/shared/components/TextArea/style.scss +0 -0
- /package/{src → build/web}/shared/components/Throbber/theme.scss +0 -0
- /package/{src → build/web}/shared/components/WithTooltip/default-theme.scss +0 -0
- /package/{src → build/web}/shared/components/YouTubeVideo/base.scss +0 -0
- /package/{src → build/web}/shared/components/YouTubeVideo/throbber.scss +0 -0
- /package/{src → build/web}/shared/components/selectors/CustomDropdown/Options/style.scss +0 -0
- /package/{src → build/web}/shared/components/selectors/CustomDropdown/theme.scss +0 -0
- /package/{src → build/web}/shared/components/selectors/NativeDropdown/theme.scss +0 -0
- /package/{src → build/web}/shared/components/selectors/Switch/theme.scss +0 -0
- /package/{src → build/web}/styles/_global/reset.css +0 -0
- /package/{src → build/web}/styles/_mixins/fonts.scss +0 -0
- /package/{src → build/web}/styles/_mixins/media.scss +0 -0
- /package/{src → build/web}/styles/_mixins/typography.scss +0 -0
- /package/{src → build/web}/styles/global.scss +0 -0
- /package/{src → build/web}/styles/mixins.scss +0 -0
|
@@ -1,104 +1,67 @@
|
|
|
1
|
+
import "core-js/modules/es.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/es.iterator.for-each.js";
|
|
3
|
+
import "core-js/modules/es.iterator.map.js";
|
|
4
|
+
import "core-js/modules/es.set.difference.v2.js";
|
|
5
|
+
import "core-js/modules/es.set.intersection.v2.js";
|
|
6
|
+
import "core-js/modules/es.set.is-disjoint-from.v2.js";
|
|
7
|
+
import "core-js/modules/es.set.is-subset-of.v2.js";
|
|
8
|
+
import "core-js/modules/es.set.is-superset-of.v2.js";
|
|
9
|
+
import "core-js/modules/es.set.symmetric-difference.v2.js";
|
|
10
|
+
import "core-js/modules/es.set.union.v2.js";
|
|
1
11
|
/**
|
|
2
12
|
* ExpressJS middleware for server-side rendering of a ReactJS app.
|
|
3
13
|
*/
|
|
4
14
|
|
|
15
|
+
import { Buffer } from 'node:buffer';
|
|
16
|
+
import { createCipheriv, randomBytes } from 'node:crypto';
|
|
5
17
|
import fs from 'node:fs';
|
|
6
18
|
import path from 'node:path';
|
|
7
19
|
import { Writable } from 'node:stream';
|
|
8
20
|
import { brotliCompress, brotliDecompress } from 'node:zlib';
|
|
9
|
-
|
|
10
|
-
import type { Request, RequestHandler } from 'express';
|
|
11
|
-
import type { ComponentType } from 'react';
|
|
12
|
-
import type { Configuration, Stats } from 'webpack';
|
|
13
21
|
import winston from 'winston';
|
|
14
|
-
|
|
15
22
|
import { GlobalStateProvider, SsrContext } from '@dr.pogodin/react-global-state';
|
|
16
23
|
import { timer } from '@dr.pogodin/js-utils';
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
clone,
|
|
20
|
-
cloneDeep,
|
|
21
|
-
defaults,
|
|
22
|
-
get,
|
|
23
|
-
isString,
|
|
24
|
-
mapValues,
|
|
25
|
-
omit,
|
|
26
|
-
} from 'lodash';
|
|
27
|
-
|
|
24
|
+
import { cloneDeep, defaults, get, mapValues } from 'lodash-es';
|
|
28
25
|
import config from 'config';
|
|
29
|
-
import forge from 'node-forge';
|
|
30
|
-
|
|
31
26
|
import { prerenderToNodeStream } from 'react-dom/static';
|
|
32
|
-
import {
|
|
27
|
+
import { HelmetProvider } from '@dr.pogodin/react-helmet';
|
|
33
28
|
import { StaticRouter } from 'react-router';
|
|
34
29
|
import serializeJs from 'serialize-javascript';
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
import type { ChunkGroupsT, SsrContextT } from 'utils/globalState';
|
|
30
|
+
import { setBuildInfo } from "../shared/utils/isomorphy/buildInfo";
|
|
31
|
+
import Cache from "./Cache";
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
// @ts-expect-error "Property 'SECRET' does not exist on type 'IConfig'."
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
35
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
36
|
+
const {
|
|
37
|
+
SECRET,
|
|
38
|
+
...sanitizedConfig
|
|
39
|
+
} = config;
|
|
42
40
|
|
|
43
41
|
// Note: These type definitions for logger are copied from Winston logger,
|
|
44
42
|
// then simplified to make it easier to fit an alternative logger into this
|
|
45
43
|
// interface.
|
|
46
44
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
47
|
-
interface LogMethodI {
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/prefer-function-type
|
|
49
|
-
(level: string, message: string, ...meta: unknown[]): void;
|
|
50
|
-
}
|
|
51
45
|
|
|
52
46
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
53
|
-
interface LeveledLogMethodI {
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/prefer-function-type
|
|
55
|
-
(message: string, ...meta: unknown[]): void;
|
|
56
|
-
}
|
|
57
47
|
|
|
58
48
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
59
|
-
export interface LoggerI {
|
|
60
|
-
debug: LeveledLogMethodI;
|
|
61
|
-
error: LeveledLogMethodI;
|
|
62
|
-
info: LeveledLogMethodI;
|
|
63
|
-
log: LogMethodI;
|
|
64
|
-
warn: LeveledLogMethodI;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export enum SCRIPT_LOCATIONS {
|
|
68
|
-
BODY_OPEN = 'BODY_OPEN',
|
|
69
|
-
DEFAULT = 'DEFAULT',
|
|
70
|
-
HEAD_OPEN = 'HEAD_OPEN',
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export class ServerSsrContext<StateT>
|
|
74
|
-
extends SsrContext<StateT>
|
|
75
|
-
implements SsrContextT<StateT> {
|
|
76
|
-
chunkGroups: ChunkGroupsT;
|
|
77
|
-
|
|
78
|
-
chunks: string[] = [];
|
|
79
|
-
|
|
80
|
-
redirectTo?: string;
|
|
81
|
-
|
|
82
|
-
req: Request;
|
|
83
49
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
50
|
+
export let SCRIPT_LOCATIONS = /*#__PURE__*/function (SCRIPT_LOCATIONS) {
|
|
51
|
+
SCRIPT_LOCATIONS["BODY_OPEN"] = "BODY_OPEN";
|
|
52
|
+
SCRIPT_LOCATIONS["DEFAULT"] = "DEFAULT";
|
|
53
|
+
SCRIPT_LOCATIONS["HEAD_OPEN"] = "HEAD_OPEN";
|
|
54
|
+
return SCRIPT_LOCATIONS;
|
|
55
|
+
}({});
|
|
56
|
+
export class ServerSsrContext extends SsrContext {
|
|
57
|
+
chunks = [];
|
|
58
|
+
status = 200;
|
|
59
|
+
constructor(req, chunkGroups, initialState) {
|
|
60
|
+
super(cloneDeep(initialState) ?? {});
|
|
92
61
|
this.chunkGroups = chunkGroups;
|
|
93
62
|
this.req = req;
|
|
94
63
|
}
|
|
95
64
|
}
|
|
96
|
-
|
|
97
|
-
type ScriptT = {
|
|
98
|
-
code: string;
|
|
99
|
-
location: SCRIPT_LOCATIONS;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
65
|
/**
|
|
103
66
|
* Reads build-time information about the app. This information is generated
|
|
104
67
|
* by our standard Webpack config for apps, and it is written into
|
|
@@ -108,9 +71,9 @@ type ScriptT = {
|
|
|
108
71
|
* @param context Webpack context path used during the build.
|
|
109
72
|
* @return Resolves to the build-time information.
|
|
110
73
|
*/
|
|
111
|
-
function getBuildInfo(context
|
|
74
|
+
function getBuildInfo(context) {
|
|
112
75
|
const url = path.resolve(context, '.build-info');
|
|
113
|
-
return JSON.parse(fs.readFileSync(url, 'utf8'))
|
|
76
|
+
return JSON.parse(fs.readFileSync(url, 'utf8'));
|
|
114
77
|
}
|
|
115
78
|
|
|
116
79
|
/**
|
|
@@ -121,11 +84,11 @@ function getBuildInfo(context: string) {
|
|
|
121
84
|
* @param buildDir
|
|
122
85
|
* @return
|
|
123
86
|
*/
|
|
124
|
-
function readChunkGroupsJson(buildDir
|
|
87
|
+
function readChunkGroupsJson(buildDir) {
|
|
125
88
|
const url = path.resolve(buildDir, '__chunk_groups__.json');
|
|
126
89
|
let res;
|
|
127
90
|
try {
|
|
128
|
-
res = JSON.parse(fs.readFileSync(url, 'utf8'))
|
|
91
|
+
res = JSON.parse(fs.readFileSync(url, 'utf8'));
|
|
129
92
|
} catch {
|
|
130
93
|
// TODO: Should we message the error here somehow?
|
|
131
94
|
res = null;
|
|
@@ -135,26 +98,15 @@ function readChunkGroupsJson(buildDir: string) {
|
|
|
135
98
|
|
|
136
99
|
/**
|
|
137
100
|
* Prepares a new Cipher for data encryption.
|
|
138
|
-
* @param key Encryption key (32-bit random key is expected
|
|
139
|
-
*
|
|
140
|
-
* @return Resolves to the object with two fields:
|
|
101
|
+
* @param key Encryption key (32-bit random, Base64-encoded key is expected).
|
|
102
|
+
* @return Returns a tuple of:
|
|
141
103
|
* 1. cipher - a new Cipher, ready for encryption;
|
|
142
104
|
* 2. iv - initial vector used by the cipher.
|
|
143
105
|
*/
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
iv
|
|
147
|
-
|
|
148
|
-
return new Promise((resolve, reject) => {
|
|
149
|
-
forge.random.getBytes(32, (err, iv) => {
|
|
150
|
-
if (err) reject(err);
|
|
151
|
-
else {
|
|
152
|
-
const cipher = forge.cipher.createCipher('AES-CBC', key);
|
|
153
|
-
cipher.start({ iv });
|
|
154
|
-
resolve({ cipher, iv });
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
});
|
|
106
|
+
function prepareCipher(key) {
|
|
107
|
+
const iv = randomBytes(16);
|
|
108
|
+
const cipher = createCipheriv('AES-256-CBC', Buffer.from(key, 'base64'), iv);
|
|
109
|
+
return [cipher, iv];
|
|
158
110
|
}
|
|
159
111
|
|
|
160
112
|
/**
|
|
@@ -162,14 +114,13 @@ async function prepareCipher(key: string): Promise<{
|
|
|
162
114
|
* are acceptable to the caller.
|
|
163
115
|
* @param req
|
|
164
116
|
*/
|
|
165
|
-
export function isBrotliAcceptable(req
|
|
117
|
+
export function isBrotliAcceptable(req) {
|
|
166
118
|
const acceptable = req.get('accept-encoding');
|
|
167
119
|
if (acceptable) {
|
|
168
120
|
const ops = acceptable.split(',');
|
|
169
121
|
for (const op of ops) {
|
|
170
122
|
const [type, priority] = op.trim().split(';q=');
|
|
171
|
-
if ((type === '*' || type === 'br')
|
|
172
|
-
&& (!priority || parseFloat(priority) > 0)) {
|
|
123
|
+
if ((type === '*' || type === 'br') && (!priority || parseFloat(priority) > 0)) {
|
|
173
124
|
return true;
|
|
174
125
|
}
|
|
175
126
|
}
|
|
@@ -191,18 +142,17 @@ export function isBrotliAcceptable(req: Request): boolean {
|
|
|
191
142
|
* HEAD_OPEN: string[];
|
|
192
143
|
* }}
|
|
193
144
|
*/
|
|
194
|
-
function groupExtraScripts(scripts
|
|
145
|
+
function groupExtraScripts(scripts = []) {
|
|
195
146
|
const res = {
|
|
196
147
|
[SCRIPT_LOCATIONS.BODY_OPEN]: '',
|
|
197
148
|
[SCRIPT_LOCATIONS.DEFAULT]: '',
|
|
198
|
-
[SCRIPT_LOCATIONS.HEAD_OPEN]: ''
|
|
149
|
+
[SCRIPT_LOCATIONS.HEAD_OPEN]: ''
|
|
199
150
|
};
|
|
200
151
|
for (const script of scripts) {
|
|
201
|
-
if (
|
|
152
|
+
if (typeof script === 'string') {
|
|
202
153
|
if (script) res[SCRIPT_LOCATIONS.DEFAULT] += script;
|
|
203
154
|
} else if (script.code) {
|
|
204
|
-
if (script.location in res) res[script.location] += script.code;
|
|
205
|
-
else throw Error(`Invalid location "${script.location}"`);
|
|
155
|
+
if (script.location in res) res[script.location] += script.code;else throw Error(`Invalid location "${script.location}"`);
|
|
206
156
|
}
|
|
207
157
|
}
|
|
208
158
|
return res;
|
|
@@ -215,70 +165,31 @@ function groupExtraScripts(scripts: Array<string | ScriptT> = []) {
|
|
|
215
165
|
* @return {object}
|
|
216
166
|
*/
|
|
217
167
|
export function newDefaultLogger({
|
|
218
|
-
defaultLogLevel = 'info'
|
|
219
|
-
} = {})
|
|
220
|
-
const {
|
|
168
|
+
defaultLogLevel = 'info'
|
|
169
|
+
} = {}) {
|
|
170
|
+
const {
|
|
171
|
+
format,
|
|
172
|
+
transports
|
|
173
|
+
} = winston;
|
|
221
174
|
return winston.createLogger({
|
|
222
|
-
format: format.combine(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
res += `\n${JSON.stringify(rest, null, 2)}`;
|
|
237
|
-
}
|
|
238
|
-
if (stack) res += `\n${stack as string}`;
|
|
239
|
-
return res;
|
|
240
|
-
},
|
|
241
|
-
),
|
|
242
|
-
),
|
|
175
|
+
format: format.combine(format.splat(), format.timestamp(), format.colorize(), format.printf(({
|
|
176
|
+
level,
|
|
177
|
+
message,
|
|
178
|
+
timestamp,
|
|
179
|
+
stack,
|
|
180
|
+
...rest
|
|
181
|
+
}) => {
|
|
182
|
+
let res = `${level}\t(at ${timestamp}):\t${message}`;
|
|
183
|
+
if (Object.keys(rest).length) {
|
|
184
|
+
res += `\n${JSON.stringify(rest, null, 2)}`;
|
|
185
|
+
}
|
|
186
|
+
if (stack) res += `\n${stack}`;
|
|
187
|
+
return res;
|
|
188
|
+
})),
|
|
243
189
|
level: defaultLogLevel,
|
|
244
|
-
transports: [new transports.Console()]
|
|
190
|
+
transports: [new transports.Console()]
|
|
245
191
|
});
|
|
246
192
|
}
|
|
247
|
-
|
|
248
|
-
export type ConfigT = {
|
|
249
|
-
[key: string]: ConfigT | string;
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
export type BeforeRenderResT = {
|
|
253
|
-
configToInject?: ConfigT;
|
|
254
|
-
extraScripts?: Array<ScriptT | string>;
|
|
255
|
-
initialState?: unknown;
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
export type BeforeRenderT = (
|
|
259
|
-
req: Request,
|
|
260
|
-
config: ConfigT,
|
|
261
|
-
) => BeforeRenderResT | Promise<BeforeRenderResT>;
|
|
262
|
-
|
|
263
|
-
type CacheRefT = {
|
|
264
|
-
key: string;
|
|
265
|
-
maxage?: number;
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
export type OptionsT = {
|
|
269
|
-
Application?: ComponentType;
|
|
270
|
-
beforeRender?: BeforeRenderT;
|
|
271
|
-
buildInfo?: BuildInfoT;
|
|
272
|
-
defaultLoggerLogLevel?: string;
|
|
273
|
-
favicon?: string;
|
|
274
|
-
logger?: LoggerI;
|
|
275
|
-
maxSsrRounds?: number;
|
|
276
|
-
noCsp?: boolean;
|
|
277
|
-
staticCacheSize?: number;
|
|
278
|
-
ssrTimeout?: number;
|
|
279
|
-
staticCacheController?: (req: Request) => CacheRefT | null | undefined;
|
|
280
|
-
};
|
|
281
|
-
|
|
282
193
|
/**
|
|
283
194
|
* Creates the middleware.
|
|
284
195
|
* @param webpackConfig
|
|
@@ -310,46 +221,36 @@ export type OptionsT = {
|
|
|
310
221
|
* If undefined - infinite age is assumed.
|
|
311
222
|
* @return Created middleware.
|
|
312
223
|
*/
|
|
313
|
-
export default function factory(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
const ops: OptionsT = defaults(clone(options), {
|
|
224
|
+
export default function factory(webpackConfig, options) {
|
|
225
|
+
const ops = defaults({
|
|
226
|
+
...options
|
|
227
|
+
}, {
|
|
318
228
|
beforeRender: async () => Promise.resolve({}),
|
|
319
229
|
maxSsrRounds: 10,
|
|
320
230
|
ssrTimeout: 1000,
|
|
321
|
-
staticCacheSize: 1.e7
|
|
231
|
+
staticCacheSize: 1.e7
|
|
322
232
|
});
|
|
323
233
|
|
|
324
234
|
// Note: in normal use the default logger is created and set in the root
|
|
325
235
|
// server function, and this initialization is for testing uses, where
|
|
326
236
|
// renderer is imported directly.
|
|
327
237
|
ops.logger ??= newDefaultLogger({
|
|
328
|
-
defaultLogLevel: ops.defaultLoggerLogLevel
|
|
238
|
+
defaultLogLevel: ops.defaultLoggerLogLevel
|
|
329
239
|
});
|
|
330
|
-
|
|
331
|
-
const buildInfo = ops.buildInfo ?? getBuildInfo(webpackConfig.context!);
|
|
240
|
+
const buildInfo = ops.buildInfo ?? getBuildInfo(webpackConfig.context);
|
|
332
241
|
setBuildInfo(buildInfo);
|
|
333
242
|
|
|
334
243
|
// publicPath from webpack.output has a trailing slash at the end.
|
|
335
|
-
const {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
244
|
+
const {
|
|
245
|
+
publicPath,
|
|
246
|
+
path: outputPath
|
|
247
|
+
} = webpackConfig.output;
|
|
248
|
+
const manifestLink = fs.existsSync(`${outputPath}/manifest.json`) ? `<link rel="manifest" href="${publicPath}manifest.json">` : '';
|
|
339
249
|
|
|
340
250
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
341
|
-
interface BufferWithNonce extends ArrayBuffer {
|
|
342
|
-
nonce: string;
|
|
343
|
-
}
|
|
344
251
|
|
|
345
|
-
const cache = ops.staticCacheController
|
|
346
|
-
|
|
347
|
-
buffer: BufferWithNonce;
|
|
348
|
-
status: number;
|
|
349
|
-
}>(ops.staticCacheSize!)
|
|
350
|
-
: null;
|
|
351
|
-
|
|
352
|
-
const CHUNK_GROUPS = readChunkGroupsJson(outputPath!);
|
|
252
|
+
const cache = ops.staticCacheController ? new Cache(ops.staticCacheSize) : null;
|
|
253
|
+
const CHUNK_GROUPS = readChunkGroupsJson(outputPath);
|
|
353
254
|
|
|
354
255
|
// TODO: Look at it later.
|
|
355
256
|
// eslint-disable-next-line complexity
|
|
@@ -357,26 +258,26 @@ export default function factory(
|
|
|
357
258
|
try {
|
|
358
259
|
// Ensures any caches always revalidate HTML markup before reuse.
|
|
359
260
|
res.set('Cache-Control', 'no-cache');
|
|
360
|
-
|
|
361
261
|
res.cookie('csrfToken', req.csrfToken());
|
|
362
|
-
|
|
363
|
-
let cacheRef: CacheRefT | null | undefined;
|
|
262
|
+
let cacheRef;
|
|
364
263
|
if (cache) {
|
|
365
|
-
cacheRef = ops.staticCacheController
|
|
264
|
+
cacheRef = ops.staticCacheController(req);
|
|
366
265
|
if (cacheRef) {
|
|
367
266
|
const data = cache.get(cacheRef);
|
|
368
267
|
if (data !== null) {
|
|
369
|
-
const {
|
|
268
|
+
const {
|
|
269
|
+
buffer,
|
|
270
|
+
status
|
|
271
|
+
} = data;
|
|
370
272
|
if (ops.noCsp && isBrotliAcceptable(req)) {
|
|
371
273
|
res.set('Content-Type', 'text/html');
|
|
372
274
|
res.set('Content-Encoding', 'br');
|
|
373
275
|
if (status !== 200) res.status(status);
|
|
374
276
|
res.send(buffer);
|
|
375
277
|
} else {
|
|
376
|
-
await new Promise
|
|
278
|
+
await new Promise((done, failed) => {
|
|
377
279
|
brotliDecompress(buffer, (error, html) => {
|
|
378
|
-
if (error) failed(error);
|
|
379
|
-
else {
|
|
280
|
+
if (error) failed(error);else {
|
|
380
281
|
let h = html.toString();
|
|
381
282
|
if (!ops.noCsp) {
|
|
382
283
|
// TODO: Starting from Node v15 we'll be able to use string's
|
|
@@ -385,9 +286,7 @@ export default function factory(
|
|
|
385
286
|
const regex = new RegExp(buffer.nonce, 'g');
|
|
386
287
|
|
|
387
288
|
// TODO: It should be implemented more careful.
|
|
388
|
-
h = h.replace(regex,
|
|
389
|
-
nonce: string;
|
|
390
|
-
}).nonce);
|
|
289
|
+
h = h.replace(regex, req.nonce);
|
|
391
290
|
}
|
|
392
291
|
if (status !== 200) res.status(status);
|
|
393
292
|
res.send(h);
|
|
@@ -400,144 +299,115 @@ export default function factory(
|
|
|
400
299
|
}
|
|
401
300
|
}
|
|
402
301
|
}
|
|
403
|
-
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
const [{
|
|
302
|
+
const brr = ops.beforeRender(req, sanitizedConfig);
|
|
303
|
+
const {
|
|
407
304
|
configToInject,
|
|
408
305
|
extraScripts,
|
|
409
|
-
initialState
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}] = await Promise.all([
|
|
414
|
-
// NOTE: Written this way to avoid triggering the "await-thenable"
|
|
415
|
-
// ESLint rule.
|
|
416
|
-
brr instanceof Promise ? brr : Promise.resolve(brr),
|
|
417
|
-
|
|
418
|
-
prepareCipher(buildInfo.key),
|
|
419
|
-
]);
|
|
420
|
-
|
|
421
|
-
let helmet: HelmetDataContext['helmet'];
|
|
306
|
+
initialState
|
|
307
|
+
} = await brr;
|
|
308
|
+
const [cipher, iv] = prepareCipher(buildInfo.key);
|
|
309
|
+
let helmet;
|
|
422
310
|
|
|
423
311
|
// Gets the mapping between code chunk names and their asset files.
|
|
424
312
|
// These data come from the Webpack compilation, either from the stats
|
|
425
313
|
// attached to the request (in dev mode), or from a file output during
|
|
426
314
|
// the build (in prod mode).
|
|
427
|
-
let chunkGroups
|
|
428
|
-
const webpackStats = get(res.locals, 'webpack.devMiddleware.stats')
|
|
315
|
+
let chunkGroups;
|
|
316
|
+
const webpackStats = get(res.locals, 'webpack.devMiddleware.stats');
|
|
429
317
|
if (webpackStats) {
|
|
430
|
-
chunkGroups = mapValues(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
);
|
|
438
|
-
} else if (CHUNK_GROUPS) chunkGroups = CHUNK_GROUPS;
|
|
439
|
-
else chunkGroups = {};
|
|
318
|
+
chunkGroups = mapValues(webpackStats.toJson({
|
|
319
|
+
all: false,
|
|
320
|
+
chunkGroups: true
|
|
321
|
+
}).namedChunkGroups, item => item.assets?.map(({
|
|
322
|
+
name
|
|
323
|
+
}) => name) ?? []);
|
|
324
|
+
} else if (CHUNK_GROUPS) chunkGroups = CHUNK_GROUPS;else chunkGroups = {};
|
|
440
325
|
|
|
441
326
|
/* Optional server-side rendering. */
|
|
442
327
|
const App = ops.Application;
|
|
443
|
-
let appHtmlMarkup
|
|
328
|
+
let appHtmlMarkup = '';
|
|
444
329
|
const ssrContext = new ServerSsrContext(req, chunkGroups, initialState);
|
|
445
|
-
let stream
|
|
330
|
+
let stream;
|
|
446
331
|
if (App) {
|
|
447
332
|
const ssrStart = Date.now();
|
|
448
333
|
|
|
449
334
|
// TODO: Somehow, without it TS does not realise that
|
|
450
335
|
// App has been checked to exist.
|
|
451
336
|
const App2 = App;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}).catch(reject);
|
|
498
|
-
},
|
|
499
|
-
);
|
|
500
|
-
|
|
337
|
+
const renderPass = async () => new Promise((resolveArg, rejectArg) => {
|
|
338
|
+
ssrContext.chunks = [];
|
|
339
|
+
|
|
340
|
+
// NOTE: JS does not have problems if resolve() and reject() methods
|
|
341
|
+
// of a Promise are called multiple times, with different arguments;
|
|
342
|
+
// it only respects the first call, and ignores subsequent ones.
|
|
343
|
+
// We, however, really want to assert that here, to safeguard against
|
|
344
|
+
// any future problems due to unexpected internal changes in React,
|
|
345
|
+
// if any.
|
|
346
|
+
let error;
|
|
347
|
+
const resolve = arg => {
|
|
348
|
+
if (error !== undefined) throw Error('Internal error');
|
|
349
|
+
error = null;
|
|
350
|
+
resolveArg(arg);
|
|
351
|
+
};
|
|
352
|
+
const reject = arg => {
|
|
353
|
+
if (error !== undefined && error !== arg) {
|
|
354
|
+
throw Error('Internal error');
|
|
355
|
+
}
|
|
356
|
+
error = arg;
|
|
357
|
+
rejectArg(arg);
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// TODO: prerenderToNodeStream has (abort) "signal" option,
|
|
361
|
+
// and we should wire it up to the SSR timeout below.
|
|
362
|
+
const helmetContext = {};
|
|
363
|
+
void prerenderToNodeStream(/*#__PURE__*/_jsx(GlobalStateProvider, {
|
|
364
|
+
initialState: ssrContext.state,
|
|
365
|
+
ssrContext: ssrContext,
|
|
366
|
+
children: /*#__PURE__*/_jsx(StaticRouter, {
|
|
367
|
+
location: req.url,
|
|
368
|
+
children: /*#__PURE__*/_jsx(HelmetProvider, {
|
|
369
|
+
context: helmetContext,
|
|
370
|
+
children: /*#__PURE__*/_jsx(App2, {})
|
|
371
|
+
})
|
|
372
|
+
})
|
|
373
|
+
}), {
|
|
374
|
+
onError: reject
|
|
375
|
+
}).then(result => {
|
|
376
|
+
({
|
|
377
|
+
helmet
|
|
378
|
+
} = helmetContext);
|
|
379
|
+
resolve(result.prelude);
|
|
380
|
+
}).catch(reject);
|
|
381
|
+
});
|
|
501
382
|
let ssrRound = 0;
|
|
502
383
|
let bailed = false;
|
|
503
|
-
for (; ssrRound < ops.maxSsrRounds
|
|
384
|
+
for (; ssrRound < ops.maxSsrRounds; ++ssrRound) {
|
|
504
385
|
stream = await renderPass();
|
|
505
|
-
|
|
506
386
|
if (!ssrContext.dirty) break;
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
bailed = timeout <= 0 || !await Promise.race([
|
|
510
|
-
Promise.allSettled(ssrContext.pending),
|
|
511
|
-
timer(timeout).then(() => false),
|
|
512
|
-
]);
|
|
387
|
+
const timeout = ops.ssrTimeout + ssrStart - Date.now();
|
|
388
|
+
bailed = timeout <= 0 || !(await Promise.race([Promise.allSettled(ssrContext.pending), timer(timeout).then(() => false)]));
|
|
513
389
|
if (bailed) break;
|
|
514
390
|
}
|
|
515
|
-
|
|
516
391
|
let logMsg;
|
|
517
392
|
if (ssrContext.dirty) {
|
|
518
393
|
// NOTE: In the case of incomplete SSR one more round is necessary
|
|
519
394
|
// to ensure the correct hydration when some pending promises have
|
|
520
395
|
// resolved and placed their data into the initial global state.
|
|
521
396
|
stream = await renderPass();
|
|
522
|
-
|
|
523
|
-
logMsg = bailed ? `SSR timed out after ${ops.ssrTimeout} second(s)`
|
|
524
|
-
: `SSR bailed out after ${ops.maxSsrRounds} round(s)`;
|
|
397
|
+
logMsg = bailed ? `SSR timed out after ${ops.ssrTimeout} second(s)` : `SSR bailed out after ${ops.maxSsrRounds} round(s)`;
|
|
525
398
|
} else logMsg = `SSR completed in ${ssrRound + 1} round(s)`;
|
|
526
|
-
|
|
527
|
-
ops.logger!.log(ssrContext.dirty ? 'warn' : 'info', logMsg);
|
|
528
|
-
|
|
399
|
+
ops.logger.log(ssrContext.dirty ? 'warn' : 'info', logMsg);
|
|
529
400
|
if (ssrContext.redirectTo) {
|
|
530
401
|
res.redirect(ssrContext.status, ssrContext.redirectTo);
|
|
531
402
|
return;
|
|
532
403
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
stream!.pipe(new Writable({
|
|
404
|
+
await new Promise(ready => {
|
|
405
|
+
stream.pipe(new Writable({
|
|
536
406
|
destroy: ready,
|
|
537
|
-
write: (chunk
|
|
407
|
+
write: (chunk, _, done) => {
|
|
538
408
|
appHtmlMarkup += chunk.toString();
|
|
539
409
|
done();
|
|
540
|
-
}
|
|
410
|
+
}
|
|
541
411
|
}));
|
|
542
412
|
});
|
|
543
413
|
}
|
|
@@ -550,16 +420,13 @@ export default function factory(
|
|
|
550
420
|
const payload = serializeJs({
|
|
551
421
|
CHUNK_GROUPS: chunkGroups,
|
|
552
422
|
CONFIG: configToInject ?? sanitizedConfig,
|
|
553
|
-
ISTATE: ssrContext.state
|
|
423
|
+
ISTATE: ssrContext.state
|
|
554
424
|
}, {
|
|
555
425
|
ignoreFunction: true,
|
|
556
|
-
unsafe: true
|
|
426
|
+
unsafe: true
|
|
557
427
|
});
|
|
558
|
-
cipher.update(
|
|
559
|
-
|
|
560
|
-
const INJ = forge.util.encode64(`${iv}${cipher.output.data}`);
|
|
561
|
-
|
|
562
|
-
const chunkSet = new Set<string>();
|
|
428
|
+
const INJ = Buffer.concat([iv, cipher.update(payload, 'utf8'), cipher.final()]).toString('base64');
|
|
429
|
+
const chunkSet = new Set();
|
|
563
430
|
|
|
564
431
|
// TODO: "main" chunk has to be added explicitly,
|
|
565
432
|
// because unlike all other chunks they are not managed by <CodeSplit>
|
|
@@ -569,35 +436,24 @@ export default function factory(
|
|
|
569
436
|
// remove or add other entry points, but it requires additional
|
|
570
437
|
// efforts to figure out how to automatically order them right,
|
|
571
438
|
// thus for now this handles the default config.
|
|
572
|
-
[
|
|
573
|
-
'main',
|
|
574
|
-
...ssrContext.chunks,
|
|
575
|
-
].forEach((chunk) => {
|
|
439
|
+
['main', ...ssrContext.chunks].forEach(chunk => {
|
|
576
440
|
const assets = chunkGroups[chunk];
|
|
577
|
-
if (assets) assets.forEach(
|
|
441
|
+
if (assets) assets.forEach(asset => chunkSet.add(asset));
|
|
578
442
|
});
|
|
579
|
-
|
|
580
443
|
let styleChunkString = '';
|
|
581
444
|
let scriptChunkString = '';
|
|
582
|
-
chunkSet.forEach(
|
|
445
|
+
chunkSet.forEach(chunk => {
|
|
583
446
|
if (chunk.endsWith('.css')) {
|
|
584
|
-
styleChunkString += `<link href="${publicPath
|
|
585
|
-
} else if (
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
) {
|
|
591
|
-
scriptChunkString += `<script src="${publicPath as string}${chunk}" type="application/javascript"></script>`;
|
|
447
|
+
styleChunkString += `<link href="${publicPath}${chunk}" rel="stylesheet">`;
|
|
448
|
+
} else if (chunk.endsWith('.js')
|
|
449
|
+
// In dev mode HMR adds JS updates into asset arrays,
|
|
450
|
+
// and they (updates) should be ignored.
|
|
451
|
+
&& !chunk.endsWith('.hot-update.js')) {
|
|
452
|
+
scriptChunkString += `<script src="${publicPath}${chunk}" type="application/javascript"></script>`;
|
|
592
453
|
}
|
|
593
454
|
});
|
|
594
|
-
|
|
595
455
|
const grouppedExtraScripts = groupExtraScripts(extraScripts);
|
|
596
|
-
|
|
597
|
-
const faviconLink = ops.favicon
|
|
598
|
-
? '<link rel="shortcut icon" href="/favicon.ico">'
|
|
599
|
-
: '';
|
|
600
|
-
|
|
456
|
+
const faviconLink = ops.favicon ? '<link rel="shortcut icon" href="/favicon.ico">' : '';
|
|
601
457
|
const html = `<!DOCTYPE html>
|
|
602
458
|
<html lang="en">
|
|
603
459
|
<head>
|
|
@@ -622,22 +478,20 @@ export default function factory(
|
|
|
622
478
|
${grouppedExtraScripts[SCRIPT_LOCATIONS.DEFAULT]}
|
|
623
479
|
</body>
|
|
624
480
|
</html>`;
|
|
625
|
-
|
|
626
481
|
const status = ssrContext.status || 200;
|
|
627
482
|
if (status !== 200) res.status(status);
|
|
628
|
-
|
|
629
483
|
if (cacheRef && status < 500) {
|
|
630
484
|
// Note: waiting for the caching to complete is not strictly necessary,
|
|
631
485
|
// but it greately simplifies testing, and error reporting.
|
|
632
|
-
await new Promise
|
|
486
|
+
await new Promise((done, failed) => {
|
|
633
487
|
brotliCompress(html, (error, buffer) => {
|
|
634
|
-
if (error) failed(error);
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
488
|
+
if (error) failed(error);else {
|
|
489
|
+
const b = buffer;
|
|
490
|
+
b.nonce = req.nonce;
|
|
491
|
+
cache.add({
|
|
492
|
+
buffer: b,
|
|
493
|
+
status
|
|
494
|
+
}, cacheRef.key, buffer.length);
|
|
641
495
|
done();
|
|
642
496
|
}
|
|
643
497
|
});
|
|
@@ -653,3 +507,4 @@ export default function factory(
|
|
|
653
507
|
}
|
|
654
508
|
};
|
|
655
509
|
}
|
|
510
|
+
//# sourceMappingURL=renderer.js.map
|