@dr.pogodin/react-utils 1.47.0-alpha.2 → 1.47.0-alpha.4

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.
Files changed (223) hide show
  1. package/babel.config.js +1 -1
  2. package/babel.module.config.js +11 -0
  3. package/bin/build.js +8 -4
  4. package/bin/setup.js +2 -3
  5. package/build/development/client/getInj.js +47 -45
  6. package/build/development/client/getInj.js.map +1 -1
  7. package/build/development/client/index.js +15 -21
  8. package/build/development/client/index.js.map +1 -1
  9. package/build/development/client/init.js +2 -6
  10. package/build/development/client/init.js.map +1 -1
  11. package/build/development/index.js +10 -179
  12. package/build/development/index.js.map +1 -1
  13. package/build/development/server/Cache.js +1 -8
  14. package/build/development/server/Cache.js.map +1 -1
  15. package/build/development/server/index.js +25 -50
  16. package/build/development/server/index.js.map +1 -1
  17. package/build/development/server/renderer.js +63 -92
  18. package/build/development/server/renderer.js.map +1 -1
  19. package/build/development/server/server.js +47 -58
  20. package/build/development/server/server.js.map +1 -1
  21. package/build/development/server/utils/errors.js +8 -31
  22. package/build/development/server/utils/errors.js.map +1 -1
  23. package/build/development/server/utils/index.js +2 -9
  24. package/build/development/server/utils/index.js.map +1 -1
  25. package/build/development/shared/components/Button/index.js +9 -16
  26. package/build/development/shared/components/Button/index.js.map +1 -1
  27. package/build/development/shared/components/Checkbox/index.js +6 -13
  28. package/build/development/shared/components/Checkbox/index.js.map +1 -1
  29. package/build/development/shared/components/GenericLink/index.js +4 -10
  30. package/build/development/shared/components/GenericLink/index.js.map +1 -1
  31. package/build/development/shared/components/Input/index.js +11 -18
  32. package/build/development/shared/components/Input/index.js.map +1 -1
  33. package/build/development/shared/components/Link.js +6 -13
  34. package/build/development/shared/components/Link.js.map +1 -1
  35. package/build/development/shared/components/Modal/index.js +16 -22
  36. package/build/development/shared/components/Modal/index.js.map +1 -1
  37. package/build/development/shared/components/NavLink.js +6 -13
  38. package/build/development/shared/components/NavLink.js.map +1 -1
  39. package/build/development/shared/components/PageLayout/index.js +7 -14
  40. package/build/development/shared/components/PageLayout/index.js.map +1 -1
  41. package/build/development/shared/components/TextArea/index.js +15 -22
  42. package/build/development/shared/components/TextArea/index.js.map +1 -1
  43. package/build/development/shared/components/Throbber/index.js +7 -14
  44. package/build/development/shared/components/Throbber/index.js.map +1 -1
  45. package/build/development/shared/components/WithTooltip/Tooltip.js +12 -18
  46. package/build/development/shared/components/WithTooltip/Tooltip.js.map +1 -1
  47. package/build/development/shared/components/WithTooltip/index.js +16 -23
  48. package/build/development/shared/components/WithTooltip/index.js.map +1 -1
  49. package/build/development/shared/components/YouTubeVideo/index.js +10 -17
  50. package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
  51. package/build/development/shared/components/index.js +16 -130
  52. package/build/development/shared/components/index.js.map +1 -1
  53. package/build/development/shared/components/selectors/CustomDropdown/Options/index.js +12 -19
  54. package/build/development/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
  55. package/build/development/shared/components/selectors/CustomDropdown/index.js +20 -28
  56. package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
  57. package/build/development/shared/components/selectors/NativeDropdown/index.js +13 -19
  58. package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
  59. package/build/development/shared/components/selectors/Switch/index.js +10 -17
  60. package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
  61. package/build/development/shared/components/selectors/common.js +1 -7
  62. package/build/development/shared/components/selectors/common.js.map +1 -1
  63. package/build/development/shared/components/selectors/index.js +3 -27
  64. package/build/development/shared/components/selectors/index.js.map +1 -1
  65. package/build/development/shared/utils/config.js +40 -20
  66. package/build/development/shared/utils/config.js.map +1 -1
  67. package/build/development/shared/utils/globalState.js +3 -8
  68. package/build/development/shared/utils/globalState.js.map +1 -1
  69. package/build/development/shared/utils/index.js +12 -89
  70. package/build/development/shared/utils/index.js.map +1 -1
  71. package/build/development/shared/utils/isomorphy/buildInfo.js +2 -9
  72. package/build/development/shared/utils/isomorphy/buildInfo.js.map +1 -1
  73. package/build/development/shared/utils/isomorphy/environment-check.js +2 -8
  74. package/build/development/shared/utils/isomorphy/environment-check.js.map +1 -1
  75. package/build/development/shared/utils/isomorphy/index.js +7 -32
  76. package/build/development/shared/utils/isomorphy/index.js.map +1 -1
  77. package/build/development/shared/utils/jest/E2eSsrEnv.js +20 -31
  78. package/build/development/shared/utils/jest/E2eSsrEnv.js.map +1 -1
  79. package/build/development/shared/utils/jest/global.js +1 -7
  80. package/build/development/shared/utils/jest/global.js.map +1 -1
  81. package/build/development/shared/utils/jest/index.js +20 -44
  82. package/build/development/shared/utils/jest/index.js.map +1 -1
  83. package/build/development/shared/utils/splitComponent.js +24 -30
  84. package/build/development/shared/utils/splitComponent.js.map +1 -1
  85. package/build/development/shared/utils/time.js +22 -31
  86. package/build/development/shared/utils/time.js.map +1 -1
  87. package/build/development/shared/utils/webpack.js +13 -16
  88. package/build/development/shared/utils/webpack.js.map +1 -1
  89. package/build/production/client/getInj.js +13 -11
  90. package/build/production/client/getInj.js.map +1 -1
  91. package/build/production/client/index.js +3 -3
  92. package/build/production/client/index.js.map +1 -1
  93. package/build/production/client/init.js +2 -2
  94. package/build/production/client/init.js.map +1 -1
  95. package/build/production/index.js +3 -2
  96. package/build/production/index.js.map +1 -1
  97. package/build/production/server/Cache.js +3 -3
  98. package/build/production/server/Cache.js.map +1 -1
  99. package/build/production/server/index.js +8 -8
  100. package/build/production/server/index.js.map +1 -1
  101. package/build/production/server/renderer.js +24 -25
  102. package/build/production/server/renderer.js.map +1 -1
  103. package/build/production/server/server.js +9 -9
  104. package/build/production/server/server.js.map +1 -1
  105. package/build/production/server/utils/errors.js +9 -9
  106. package/build/production/server/utils/errors.js.map +1 -1
  107. package/build/production/server/utils/index.js +2 -1
  108. package/build/production/server/utils/index.js.map +1 -1
  109. package/build/production/shared/components/Button/index.js +4 -4
  110. package/build/production/shared/components/Button/index.js.map +1 -1
  111. package/build/production/shared/components/Checkbox/index.js +1 -1
  112. package/build/production/shared/components/Checkbox/index.js.map +1 -1
  113. package/build/production/shared/components/GenericLink/index.js +4 -4
  114. package/build/production/shared/components/GenericLink/index.js.map +1 -1
  115. package/build/production/shared/components/Input/index.js +5 -5
  116. package/build/production/shared/components/Input/index.js.map +1 -1
  117. package/build/production/shared/components/Link.js +3 -3
  118. package/build/production/shared/components/Link.js.map +1 -1
  119. package/build/production/shared/components/Modal/index.js +7 -7
  120. package/build/production/shared/components/Modal/index.js.map +1 -1
  121. package/build/production/shared/components/NavLink.js +2 -2
  122. package/build/production/shared/components/NavLink.js.map +1 -1
  123. package/build/production/shared/components/PageLayout/index.js +2 -2
  124. package/build/production/shared/components/PageLayout/index.js.map +1 -1
  125. package/build/production/shared/components/TextArea/index.js +5 -5
  126. package/build/production/shared/components/TextArea/index.js.map +1 -1
  127. package/build/production/shared/components/Throbber/index.js +2 -2
  128. package/build/production/shared/components/Throbber/index.js.map +1 -1
  129. package/build/production/shared/components/WithTooltip/Tooltip.js +4 -4
  130. package/build/production/shared/components/WithTooltip/Tooltip.js.map +1 -1
  131. package/build/production/shared/components/WithTooltip/index.js +4 -4
  132. package/build/production/shared/components/WithTooltip/index.js.map +1 -1
  133. package/build/production/shared/components/YouTubeVideo/index.js +4 -4
  134. package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
  135. package/build/production/shared/components/index.js +3 -1
  136. package/build/production/shared/components/index.js.map +1 -1
  137. package/build/production/shared/components/selectors/CustomDropdown/Options/index.js +2 -2
  138. package/build/production/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
  139. package/build/production/shared/components/selectors/CustomDropdown/index.js +2 -2
  140. package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -1
  141. package/build/production/shared/components/selectors/NativeDropdown/index.js +4 -4
  142. package/build/production/shared/components/selectors/NativeDropdown/index.js.map +1 -1
  143. package/build/production/shared/components/selectors/Switch/index.js +1 -1
  144. package/build/production/shared/components/selectors/Switch/index.js.map +1 -1
  145. package/build/production/shared/components/selectors/common.js +2 -2
  146. package/build/production/shared/components/selectors/common.js.map +1 -1
  147. package/build/production/shared/components/selectors/index.js +1 -1
  148. package/build/production/shared/components/selectors/index.js.map +1 -1
  149. package/build/production/shared/utils/config.js +8 -4
  150. package/build/production/shared/utils/config.js.map +1 -1
  151. package/build/production/shared/utils/globalState.js +2 -2
  152. package/build/production/shared/utils/globalState.js.map +1 -1
  153. package/build/production/shared/utils/index.js +1 -1
  154. package/build/production/shared/utils/index.js.map +1 -1
  155. package/build/production/shared/utils/isomorphy/buildInfo.js +3 -3
  156. package/build/production/shared/utils/isomorphy/buildInfo.js.map +1 -1
  157. package/build/production/shared/utils/isomorphy/environment-check.js +3 -3
  158. package/build/production/shared/utils/isomorphy/environment-check.js.map +1 -1
  159. package/build/production/shared/utils/isomorphy/index.js +4 -4
  160. package/build/production/shared/utils/isomorphy/index.js.map +1 -1
  161. package/build/production/shared/utils/jest/E2eSsrEnv.js +14 -14
  162. package/build/production/shared/utils/jest/E2eSsrEnv.js.map +1 -1
  163. package/build/production/shared/utils/jest/global.js +1 -1
  164. package/build/production/shared/utils/jest/global.js.map +1 -1
  165. package/build/production/shared/utils/jest/index.js +11 -11
  166. package/build/production/shared/utils/jest/index.js.map +1 -1
  167. package/build/production/shared/utils/splitComponent.js +11 -11
  168. package/build/production/shared/utils/splitComponent.js.map +1 -1
  169. package/build/production/shared/utils/time.js +3 -3
  170. package/build/production/shared/utils/time.js.map +1 -1
  171. package/build/production/shared/utils/webpack.js +6 -6
  172. package/build/production/shared/utils/webpack.js.map +1 -1
  173. package/build/types-code/client/getInj.d.ts +1 -2
  174. package/build/types-code/client/index.d.ts +1 -1
  175. package/build/types-code/index.d.ts +1 -1
  176. package/build/types-code/server/index.d.ts +2 -2
  177. package/build/types-code/shared/utils/config.d.ts +4 -2
  178. package/build/types-code/shared/utils/index.d.ts +2 -2
  179. package/build/types-code/shared/utils/splitComponent.d.ts +6 -4
  180. package/build/web/client/getInj.js +48 -37
  181. package/build/web/client/getInj.js.map +1 -1
  182. package/build/web/client/index.js +3 -2
  183. package/build/web/client/index.js.map +1 -1
  184. package/build/web/index.js +3 -3
  185. package/build/web/index.js.map +1 -1
  186. package/build/web/server/index.js +9 -15
  187. package/build/web/server/index.js.map +1 -1
  188. package/build/web/server/renderer.js +24 -40
  189. package/build/web/server/renderer.js.map +1 -1
  190. package/build/web/server/server.js +2 -4
  191. package/build/web/server/server.js.map +1 -1
  192. package/build/web/shared/components/Modal/index.js +2 -2
  193. package/build/web/shared/components/Modal/index.js.map +1 -1
  194. package/build/web/shared/utils/config.js +36 -10
  195. package/build/web/shared/utils/config.js.map +1 -1
  196. package/build/web/shared/utils/index.js +2 -2
  197. package/build/web/shared/utils/index.js.map +1 -1
  198. package/build/web/shared/utils/jest/E2eSsrEnv.js +1 -2
  199. package/build/web/shared/utils/jest/E2eSsrEnv.js.map +1 -1
  200. package/build/web/shared/utils/splitComponent.js +2 -1
  201. package/build/web/shared/utils/splitComponent.js.map +1 -1
  202. package/build/web/shared/utils/webpack.js +11 -7
  203. package/build/web/shared/utils/webpack.js.map +1 -1
  204. package/config/babel/node-ssr.js +5 -5
  205. package/config/jest/default.js +1 -0
  206. package/config/jest/setup.js +8 -1
  207. package/config/webpack/app-base.js +13 -12
  208. package/config/webpack/app-development.js +3 -3
  209. package/config/webpack/lib-base.js +1 -2
  210. package/package.json +9 -9
  211. package/src/client/getInj.ts +60 -40
  212. package/src/client/index.tsx +5 -3
  213. package/src/index.ts +3 -3
  214. package/src/server/index.ts +9 -15
  215. package/src/server/renderer.tsx +27 -45
  216. package/src/server/server.ts +2 -4
  217. package/src/shared/components/Modal/index.tsx +2 -2
  218. package/src/shared/utils/config.ts +48 -12
  219. package/src/shared/utils/index.ts +2 -2
  220. package/src/shared/utils/jest/E2eSsrEnv.ts +1 -2
  221. package/src/shared/utils/splitComponent.tsx +14 -2
  222. package/src/shared/utils/webpack.ts +14 -8
  223. package/types.d.ts +1 -6
@@ -1,19 +1,3 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = void 0;
8
- var _nodePath = _interopRequireDefault(require("node:path"));
9
- var _defaults = _interopRequireDefault(require("lodash/defaults"));
10
- var _set = _interopRequireDefault(require("lodash/set"));
11
- var _experimentalWorker = _interopRequireDefault(require("@babel/register/experimental-worker"));
12
- var _jestEnvironmentJsdom = _interopRequireDefault(require("jest-environment-jsdom"));
13
- var _memfs = require("memfs");
14
- var _webpack = _interopRequireDefault(require("webpack"));
15
- var _renderer = _interopRequireDefault(require("../../../server/renderer"));
16
- var _buildInfo = require("../isomorphy/buildInfo");
17
1
  /**
18
2
  * Jest environment for end-to-end SSR and client-side testing. It relies on
19
3
  * the standard react-utils mechanics to execute SSR of given scene, and also
@@ -32,16 +16,22 @@ var _buildInfo = require("../isomorphy/buildInfo");
32
16
 
33
17
  // TODO: We need to add correct typing for environment options.
34
18
 
19
+ import path from 'node:path';
20
+ import { defaults, set } from 'lodash-es';
35
21
  // As this environment is a part of the Jest testing utils,
36
22
  // we assume development dependencies are available when it is used.
37
23
  /* eslint-disable import/no-extraneous-dependencies */
38
-
24
+ import register from '@babel/register/experimental-worker';
25
+ import JsdomEnv from 'jest-environment-jsdom';
26
+ import { Volume, createFsFromVolume } from 'memfs';
27
+ import webpack from 'webpack';
39
28
  /* eslint-enable import/no-extraneous-dependencies */
40
-
29
+ import ssrFactory from "../../../server/renderer.js";
30
+ import { setBuildInfo } from "../isomorphy/buildInfo.js";
41
31
  function noop() {
42
32
  // NOOP
43
33
  }
44
- class E2eSsrEnv extends _jestEnvironmentJsdom.default {
34
+ export default class E2eSsrEnv extends JsdomEnv {
45
35
  /**
46
36
  * Loads Webpack config, and exposes it to the environment via global
47
37
  * webpackConfig object.
@@ -49,13 +39,13 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
49
39
  loadWebpackConfig() {
50
40
  const optionsString = this.pragmas['webpack-config-options'];
51
41
  const options = optionsString ? JSON.parse(optionsString) : {};
52
- (0, _defaults.default)(options, {
42
+ defaults(options, {
53
43
  context: this.testFolder,
54
44
  fs: this.global.webpackOutputFs
55
45
  });
56
46
  const factoryPath = this.pragmas['webpack-config-factory'];
57
47
  // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-require-imports
58
- let factory = require(_nodePath.default.resolve(this.rootDir, factoryPath));
48
+ let factory = require(path.resolve(this.rootDir, factoryPath));
59
49
  factory = 'default' in factory ? factory.default : factory;
60
50
  this.global.webpackConfig = factory(options);
61
51
  const fs = this.global.webpackOutputFs;
@@ -73,7 +63,7 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
73
63
  async runWebpack() {
74
64
  this.loadWebpackConfig();
75
65
  if (!this.global.webpackConfig) throw Error('Failed to load Webpack config');
76
- const compiler = (0, _webpack.default)(this.global.webpackConfig);
66
+ const compiler = webpack(this.global.webpackConfig);
77
67
  if (!compiler) throw Error('Failed to construct Webpack compiler');
78
68
 
79
69
  // TODO: The "as typeof compiler.outputFileSystem" piece below is
@@ -112,7 +102,7 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
112
102
  options.buildInfo ??= this.global.buildInfo;
113
103
  let cleanup;
114
104
  if (options.entry) {
115
- const p = _nodePath.default.resolve(this.testFolder, options.entry);
105
+ const p = path.resolve(this.testFolder, options.entry);
116
106
  // TODO: This sure can be replaced by a dynamic import().
117
107
  // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-require-imports
118
108
  const module = require(p);
@@ -122,7 +112,7 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
122
112
  options.Application = module[exportName];
123
113
  }
124
114
  }
125
- const renderer = (0, _renderer.default)(this.global.webpackConfig, options);
115
+ const renderer = ssrFactory(this.global.webpackConfig, options);
126
116
  let status = 200; // OK
127
117
  const markup = await new Promise((done, fail) => {
128
118
  void renderer(this.ssrRequest,
@@ -165,17 +155,17 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
165
155
  request.csrfToken = noop;
166
156
 
167
157
  // This ensures the initial JsDom URL matches the value we use for SSR.
168
- (0, _set.default)(config.projectConfig, 'testEnvironmentOptions.url', `http://localhost${request.url}`);
158
+ set(config.projectConfig, 'testEnvironmentOptions.url', `http://localhost${request.url}`);
169
159
  super(config, context);
170
160
  this.global.dom = this.dom;
171
- this.global.webpackOutputFs = (0, _memfs.createFsFromVolume)(new _memfs.Volume());
161
+ this.global.webpackOutputFs = createFsFromVolume(new Volume());
172
162
 
173
163
  // Extracts necessary settings from config and context.
174
164
  const {
175
165
  projectConfig
176
166
  } = config;
177
167
  this.rootDir = projectConfig.rootDir;
178
- this.testFolder = _nodePath.default.dirname(context.testPath);
168
+ this.testFolder = path.dirname(context.testPath);
179
169
  this.withSsr = !pragmas['no-ssr'];
180
170
  this.ssrRequest = request;
181
171
  this.pragmas = pragmas;
@@ -192,7 +182,7 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
192
182
  default:
193
183
  root = process.cwd();
194
184
  }
195
- (0, _experimentalWorker.default)({
185
+ register({
196
186
  envName: options.babelEnv,
197
187
  extensions: ['.js', '.jsx', '.ts', '.tsx', '.svg'],
198
188
  root
@@ -215,7 +205,7 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
215
205
  // triggers an error on the subsequent test using the environment.
216
206
  // TODO: Look for a cleaner solution.
217
207
  require.cache = {};
218
- (0, _buildInfo.setBuildInfo)(undefined, true);
208
+ setBuildInfo(undefined, true);
219
209
  if (this.withSsr) await this.runSsr();
220
210
  this.global.REACT_UTILS_FORCE_CLIENT_SIDE = true;
221
211
  }
@@ -231,9 +221,8 @@ class E2eSsrEnv extends _jestEnvironmentJsdom.default {
231
221
  Object.keys(require.cache).forEach(key => {
232
222
  delete require.cache[key];
233
223
  });
234
- _experimentalWorker.default.revert();
224
+ register.revert();
235
225
  await super.teardown();
236
226
  }
237
227
  }
238
- exports.default = E2eSsrEnv;
239
228
  //# sourceMappingURL=E2eSsrEnv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"E2eSsrEnv.js","names":["_nodePath","_interopRequireDefault","require","_defaults","_set","_experimentalWorker","_jestEnvironmentJsdom","_memfs","_webpack","_renderer","_buildInfo","noop","E2eSsrEnv","JsdomEnv","loadWebpackConfig","optionsString","pragmas","options","JSON","parse","defaults","context","testFolder","fs","global","webpackOutputFs","factoryPath","factory","path","resolve","rootDir","default","webpackConfig","buildInfo","existsSync","readFileSync","runWebpack","Error","compiler","webpack","outputFileSystem","Promise","done","fail","run","err","stats","hasErrors","console","error","toJson","errors","webpackStats","runSsr","logger","debug","info","log","warn","cleanup","entry","p","module","exportName","entryExportName","Application","renderer","ssrFactory","status","markup","ssrRequest","cookie","send","set","value","locals","devMiddleware","ssrMarkup","ssrOptions","ssrStatus","constructor","config","docblockPragmas","requestString","request","url","csrfToken","projectConfig","dom","createFsFromVolume","Volume","dirname","testPath","withSsr","root","process","cwd","register","envName","babelEnv","extensions","setup","cache","setBuildInfo","undefined","REACT_UTILS_FORCE_CLIENT_SIDE","teardown","Object","keys","forEach","key","revert","exports"],"sources":["../../../../../src/shared/utils/jest/E2eSsrEnv.ts"],"sourcesContent":["/**\n * Jest environment for end-to-end SSR and client-side testing. It relies on\n * the standard react-utils mechanics to execute SSR of given scene, and also\n * Webpack build of the code for client-side execution, it further exposes\n * Jsdom environment for the client-side testing of the outcomes.\n */\n\n// BEWARE: The module is not imported into the JU module / the main assembly of\n// the library, because doing so easily breaks stuff:\n// 1) This module depends on Node-specific modules, which would make JU\n// incompatible with JsDom if included into JU.\n// 2) If this module is weakly imported from somewhere else in the lib,\n// it seems to randomly break tests using it for a different reason,\n// probably some sort of a require-loop, or some issues with weak\n// require in that scenario.\n\n// TODO: We need to add correct typing for environment options.\n\nimport path from 'node:path';\n\nimport type { Request, Response } from 'express';\n\nimport defaults from 'lodash/defaults';\nimport set from 'lodash/set';\n\nimport type { ReactNode } from 'react';\n\n// As this environment is a part of the Jest testing utils,\n// we assume development dependencies are available when it is used.\n/* eslint-disable import/no-extraneous-dependencies */\nimport register from '@babel/register/experimental-worker';\n\nimport JsdomEnv from 'jest-environment-jsdom';\nimport { Volume, createFsFromVolume } from 'memfs';\nimport webpack, { type Configuration } from 'webpack';\n/* eslint-enable import/no-extraneous-dependencies */\n\nimport type {\n EnvironmentContext,\n JestEnvironmentConfig,\n} from '@jest/environment';\n\nimport ssrFactory from 'server/renderer';\n\nimport { setBuildInfo } from '../isomorphy/buildInfo';\n\nfunction noop() {\n // NOOP\n}\n\nexport default class E2eSsrEnv extends JsdomEnv {\n pragmas: Record<string, string | string[]>;\n\n ssrRequest: object;\n\n rootDir: string;\n\n testFolder: string;\n\n withSsr: boolean;\n\n webpackStats?: webpack.StatsCompilation;\n\n /**\n * Loads Webpack config, and exposes it to the environment via global\n * webpackConfig object.\n */\n private loadWebpackConfig() {\n const optionsString = this.pragmas['webpack-config-options'] as string;\n\n const options = (optionsString ? JSON.parse(optionsString) : {}) as\n webpack.Configuration;\n\n defaults(options, {\n context: this.testFolder,\n fs: this.global.webpackOutputFs,\n });\n\n const factoryPath = this.pragmas['webpack-config-factory'] as string;\n // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-require-imports\n let factory = require(path.resolve(this.rootDir, factoryPath)) as\n (((ops: Configuration) => Configuration) | {\n default: (ops: Configuration) => Configuration;\n });\n factory = 'default' in factory ? factory.default : factory;\n\n this.global.webpackConfig = factory(options);\n\n const fs = this.global.webpackOutputFs;\n let buildInfo = `${options.context}/.build-info`;\n if (fs.existsSync(buildInfo)) {\n buildInfo = fs.readFileSync(buildInfo, 'utf8') as string;\n this.global.buildInfo = JSON.parse(buildInfo);\n }\n }\n\n /**\n * Executes Webpack build.\n * @return {Promise}\n */\n async runWebpack(): Promise<void> {\n this.loadWebpackConfig();\n\n if (!this.global.webpackConfig) throw Error('Failed to load Webpack config');\n const compiler = webpack(this.global.webpackConfig);\n if (!compiler) throw Error('Failed to construct Webpack compiler');\n\n // TODO: The \"as typeof compiler.outputFileSystem\" piece below is\n // a workaround for the Webpack regression:\n // https://github.com/webpack/webpack/issues/18242\n compiler.outputFileSystem = this.global.webpackOutputFs as\n typeof compiler.outputFileSystem;\n\n return new Promise<void>((done, fail) => {\n compiler.run((err, stats) => {\n if (err) fail(err);\n if (stats?.hasErrors()) {\n // eslint-disable-next-line no-console\n console.error(stats.toJson().errors);\n fail(Error('Webpack compilation failed'));\n }\n\n this.global.webpackStats = stats?.toJson();\n\n // Keeps reference to the raw Webpack stats object, which should be\n // explicitly passed to the server-side renderer alongside the request,\n // so that it can to pick up asset paths for different named chunks.\n this.webpackStats = stats;\n\n done();\n });\n });\n }\n\n async runSsr(): Promise<void> {\n const optionsString = this.pragmas['ssr-options'] as string;\n const options = optionsString\n ? JSON.parse(optionsString) as Record<string, unknown>\n : {};\n\n // TODO: This is temporary to shortcut the logging added to SSR.\n options.logger ??= {\n debug: noop,\n info: noop,\n log: noop,\n warn: noop,\n };\n\n options.buildInfo ??= this.global.buildInfo;\n\n let cleanup: (() => void) | undefined;\n\n if (options.entry) {\n const p = path.resolve(this.testFolder, options.entry as string);\n // TODO: This sure can be replaced by a dynamic import().\n // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-require-imports\n const module = require(p) as NodeJS.Module;\n if ('cleanup' in module) cleanup = module.cleanup as () => void;\n\n const exportName = (options.entryExportName as string) || 'default';\n if (exportName in module) {\n options.Application = (\n module as unknown as Record<string, unknown>\n )[exportName] as ReactNode;\n }\n }\n\n const renderer = ssrFactory(this.global.webpackConfig!, options);\n let status = 200; // OK\n const markup = await new Promise<string>((done, fail) => {\n void renderer(\n this.ssrRequest as Request,\n\n // TODO: This will do for now, with the current implementation of\n // the renderer, but it will require a rework once the renderer is\n // updated to do streaming.\n ({\n cookie: noop,\n send: done,\n set: noop,\n status: (value: number) => {\n status = value;\n },\n\n // This is how up-to-date Webpack stats are passed to the server in\n // development mode, and we use this here always, instead of having\n // to pass some information via filesystem.\n locals: {\n webpack: {\n devMiddleware: {\n stats: this.webpackStats,\n },\n },\n },\n } as unknown) as Response,\n\n (error) => {\n // TODO: Strictly speaking, that error as Error casting is not all\n // correct, but it works, so no need to spend time on it right now.\n if (error) fail(error as Error);\n else done('');\n },\n );\n });\n\n this.global.ssrMarkup = markup;\n this.global.ssrOptions = options;\n this.global.ssrStatus = status;\n\n if (cleanup) cleanup();\n }\n\n constructor(\n config: JestEnvironmentConfig,\n context: EnvironmentContext,\n ) {\n const pragmas = context.docblockPragmas;\n\n const requestString = pragmas['ssr-request'] as string;\n const request = requestString\n ? JSON.parse(requestString) as Record<string, unknown>\n : {};\n\n request.url ??= '/';\n request.csrfToken = noop;\n\n // This ensures the initial JsDom URL matches the value we use for SSR.\n set(\n config.projectConfig,\n 'testEnvironmentOptions.url',\n `http://localhost${request.url as string}`,\n );\n\n super(config, context);\n\n this.global.dom = this.dom;\n this.global.webpackOutputFs = createFsFromVolume(new Volume());\n\n // Extracts necessary settings from config and context.\n const { projectConfig } = config;\n this.rootDir = projectConfig.rootDir;\n this.testFolder = path.dirname(context.testPath);\n this.withSsr = !pragmas['no-ssr'];\n this.ssrRequest = request;\n this.pragmas = pragmas;\n\n // The usual \"babel-jest\" transformation setup does not apply to\n // the environment code and imports from it, this workaround enables it.\n const optionsString = this.pragmas['ssr-options'] as string;\n const options = optionsString\n ? JSON.parse(optionsString) as Record<string, unknown>\n : {};\n let root;\n switch (options.root) {\n case 'TEST':\n root = this.testFolder;\n break;\n default: root = process.cwd();\n }\n register({\n envName: options.babelEnv as string,\n extensions: ['.js', '.jsx', '.ts', '.tsx', '.svg'],\n root,\n });\n }\n\n async setup(): Promise<void> {\n await super.setup();\n await this.runWebpack();\n\n // NOTE: It is possible that the Webpack run above, and the SSR run below\n // load different versions of the same module (CommonJS, and ES), and it may\n // cause very confusing problems (e.g. see:\n // https://github.com/birdofpreyru/react-utils/issues/413).\n // It seems we can't reset the cache of ES modules, and Jest's module reset\n // does not reset modules loaded in this enviroment module, and also only\n // replacing entire cache object by and empty {} seems to help (in contrast\n // to deleting all entries by their keys, as it is done within .teardown()\n // method below). Thus, for now we do this as a hotfix, and we also reset\n // build info to undefined, because ES module version not beeing reset\n // triggers an error on the subsequent test using the environment.\n // TODO: Look for a cleaner solution.\n require.cache = {};\n setBuildInfo(undefined, true);\n\n if (this.withSsr) await this.runSsr();\n this.global.REACT_UTILS_FORCE_CLIENT_SIDE = true;\n }\n\n async teardown(): Promise<void> {\n delete this.global.REACT_UTILS_FORCE_CLIENT_SIDE;\n\n // Resets module cache and @babel/register. Effectively this ensures that\n // the next time an instance of this environment is set up, all modules are\n // transformed by Babel from scratch, thus taking into account the latest\n // Babel config (which may change between different environment instances,\n // which does not seem to be taken into account by Babel / Node caches\n // automatically).\n Object.keys(require.cache).forEach((key) => {\n delete require.cache[key];\n });\n register.revert();\n await super.teardown();\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"E2eSsrEnv.js","names":["path","defaults","set","register","JsdomEnv","Volume","createFsFromVolume","webpack","ssrFactory","setBuildInfo","noop","E2eSsrEnv","loadWebpackConfig","optionsString","pragmas","options","JSON","parse","context","testFolder","fs","global","webpackOutputFs","factoryPath","factory","require","resolve","rootDir","default","webpackConfig","buildInfo","existsSync","readFileSync","runWebpack","Error","compiler","outputFileSystem","Promise","done","fail","run","err","stats","hasErrors","console","error","toJson","errors","webpackStats","runSsr","logger","debug","info","log","warn","cleanup","entry","p","module","exportName","entryExportName","Application","renderer","status","markup","ssrRequest","cookie","send","value","locals","devMiddleware","ssrMarkup","ssrOptions","ssrStatus","constructor","config","docblockPragmas","requestString","request","url","csrfToken","projectConfig","dom","dirname","testPath","withSsr","root","process","cwd","envName","babelEnv","extensions","setup","cache","undefined","REACT_UTILS_FORCE_CLIENT_SIDE","teardown","Object","keys","forEach","key","revert"],"sources":["../../../../../src/shared/utils/jest/E2eSsrEnv.ts"],"sourcesContent":["/**\n * Jest environment for end-to-end SSR and client-side testing. It relies on\n * the standard react-utils mechanics to execute SSR of given scene, and also\n * Webpack build of the code for client-side execution, it further exposes\n * Jsdom environment for the client-side testing of the outcomes.\n */\n\n// BEWARE: The module is not imported into the JU module / the main assembly of\n// the library, because doing so easily breaks stuff:\n// 1) This module depends on Node-specific modules, which would make JU\n// incompatible with JsDom if included into JU.\n// 2) If this module is weakly imported from somewhere else in the lib,\n// it seems to randomly break tests using it for a different reason,\n// probably some sort of a require-loop, or some issues with weak\n// require in that scenario.\n\n// TODO: We need to add correct typing for environment options.\n\nimport path from 'node:path';\n\nimport type { Request, Response } from 'express';\n\nimport { defaults, set } from 'lodash-es';\n\nimport type { ReactNode } from 'react';\n\n// As this environment is a part of the Jest testing utils,\n// we assume development dependencies are available when it is used.\n/* eslint-disable import/no-extraneous-dependencies */\nimport register from '@babel/register/experimental-worker';\n\nimport JsdomEnv from 'jest-environment-jsdom';\nimport { Volume, createFsFromVolume } from 'memfs';\nimport webpack, { type Configuration } from 'webpack';\n/* eslint-enable import/no-extraneous-dependencies */\n\nimport type {\n EnvironmentContext,\n JestEnvironmentConfig,\n} from '@jest/environment';\n\nimport ssrFactory from 'server/renderer';\n\nimport { setBuildInfo } from '../isomorphy/buildInfo';\n\nfunction noop() {\n // NOOP\n}\n\nexport default class E2eSsrEnv extends JsdomEnv {\n pragmas: Record<string, string | string[]>;\n\n ssrRequest: object;\n\n rootDir: string;\n\n testFolder: string;\n\n withSsr: boolean;\n\n webpackStats?: webpack.StatsCompilation;\n\n /**\n * Loads Webpack config, and exposes it to the environment via global\n * webpackConfig object.\n */\n private loadWebpackConfig() {\n const optionsString = this.pragmas['webpack-config-options'] as string;\n\n const options = (optionsString ? JSON.parse(optionsString) : {}) as\n webpack.Configuration;\n\n defaults(options, {\n context: this.testFolder,\n fs: this.global.webpackOutputFs,\n });\n\n const factoryPath = this.pragmas['webpack-config-factory'] as string;\n // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-require-imports\n let factory = require(path.resolve(this.rootDir, factoryPath)) as\n (((ops: Configuration) => Configuration) | {\n default: (ops: Configuration) => Configuration;\n });\n factory = 'default' in factory ? factory.default : factory;\n\n this.global.webpackConfig = factory(options);\n\n const fs = this.global.webpackOutputFs;\n let buildInfo = `${options.context}/.build-info`;\n if (fs.existsSync(buildInfo)) {\n buildInfo = fs.readFileSync(buildInfo, 'utf8') as string;\n this.global.buildInfo = JSON.parse(buildInfo);\n }\n }\n\n /**\n * Executes Webpack build.\n * @return {Promise}\n */\n async runWebpack(): Promise<void> {\n this.loadWebpackConfig();\n\n if (!this.global.webpackConfig) throw Error('Failed to load Webpack config');\n const compiler = webpack(this.global.webpackConfig);\n if (!compiler) throw Error('Failed to construct Webpack compiler');\n\n // TODO: The \"as typeof compiler.outputFileSystem\" piece below is\n // a workaround for the Webpack regression:\n // https://github.com/webpack/webpack/issues/18242\n compiler.outputFileSystem = this.global.webpackOutputFs as\n typeof compiler.outputFileSystem;\n\n return new Promise<void>((done, fail) => {\n compiler.run((err, stats) => {\n if (err) fail(err);\n if (stats?.hasErrors()) {\n // eslint-disable-next-line no-console\n console.error(stats.toJson().errors);\n fail(Error('Webpack compilation failed'));\n }\n\n this.global.webpackStats = stats?.toJson();\n\n // Keeps reference to the raw Webpack stats object, which should be\n // explicitly passed to the server-side renderer alongside the request,\n // so that it can to pick up asset paths for different named chunks.\n this.webpackStats = stats;\n\n done();\n });\n });\n }\n\n async runSsr(): Promise<void> {\n const optionsString = this.pragmas['ssr-options'] as string;\n const options = optionsString\n ? JSON.parse(optionsString) as Record<string, unknown>\n : {};\n\n // TODO: This is temporary to shortcut the logging added to SSR.\n options.logger ??= {\n debug: noop,\n info: noop,\n log: noop,\n warn: noop,\n };\n\n options.buildInfo ??= this.global.buildInfo;\n\n let cleanup: (() => void) | undefined;\n\n if (options.entry) {\n const p = path.resolve(this.testFolder, options.entry as string);\n // TODO: This sure can be replaced by a dynamic import().\n // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-require-imports\n const module = require(p) as NodeJS.Module;\n if ('cleanup' in module) cleanup = module.cleanup as () => void;\n\n const exportName = (options.entryExportName as string) || 'default';\n if (exportName in module) {\n options.Application = (\n module as unknown as Record<string, unknown>\n )[exportName] as ReactNode;\n }\n }\n\n const renderer = ssrFactory(this.global.webpackConfig!, options);\n let status = 200; // OK\n const markup = await new Promise<string>((done, fail) => {\n void renderer(\n this.ssrRequest as Request,\n\n // TODO: This will do for now, with the current implementation of\n // the renderer, but it will require a rework once the renderer is\n // updated to do streaming.\n ({\n cookie: noop,\n send: done,\n set: noop,\n status: (value: number) => {\n status = value;\n },\n\n // This is how up-to-date Webpack stats are passed to the server in\n // development mode, and we use this here always, instead of having\n // to pass some information via filesystem.\n locals: {\n webpack: {\n devMiddleware: {\n stats: this.webpackStats,\n },\n },\n },\n } as unknown) as Response,\n\n (error) => {\n // TODO: Strictly speaking, that error as Error casting is not all\n // correct, but it works, so no need to spend time on it right now.\n if (error) fail(error as Error);\n else done('');\n },\n );\n });\n\n this.global.ssrMarkup = markup;\n this.global.ssrOptions = options;\n this.global.ssrStatus = status;\n\n if (cleanup) cleanup();\n }\n\n constructor(\n config: JestEnvironmentConfig,\n context: EnvironmentContext,\n ) {\n const pragmas = context.docblockPragmas;\n\n const requestString = pragmas['ssr-request'] as string;\n const request = requestString\n ? JSON.parse(requestString) as Record<string, unknown>\n : {};\n\n request.url ??= '/';\n request.csrfToken = noop;\n\n // This ensures the initial JsDom URL matches the value we use for SSR.\n set(\n config.projectConfig,\n 'testEnvironmentOptions.url',\n `http://localhost${request.url as string}`,\n );\n\n super(config, context);\n\n this.global.dom = this.dom;\n this.global.webpackOutputFs = createFsFromVolume(new Volume());\n\n // Extracts necessary settings from config and context.\n const { projectConfig } = config;\n this.rootDir = projectConfig.rootDir;\n this.testFolder = path.dirname(context.testPath);\n this.withSsr = !pragmas['no-ssr'];\n this.ssrRequest = request;\n this.pragmas = pragmas;\n\n // The usual \"babel-jest\" transformation setup does not apply to\n // the environment code and imports from it, this workaround enables it.\n const optionsString = this.pragmas['ssr-options'] as string;\n const options = optionsString\n ? JSON.parse(optionsString) as Record<string, unknown>\n : {};\n let root;\n switch (options.root) {\n case 'TEST':\n root = this.testFolder;\n break;\n default: root = process.cwd();\n }\n register({\n envName: options.babelEnv as string,\n extensions: ['.js', '.jsx', '.ts', '.tsx', '.svg'],\n root,\n });\n }\n\n async setup(): Promise<void> {\n await super.setup();\n await this.runWebpack();\n\n // NOTE: It is possible that the Webpack run above, and the SSR run below\n // load different versions of the same module (CommonJS, and ES), and it may\n // cause very confusing problems (e.g. see:\n // https://github.com/birdofpreyru/react-utils/issues/413).\n // It seems we can't reset the cache of ES modules, and Jest's module reset\n // does not reset modules loaded in this enviroment module, and also only\n // replacing entire cache object by and empty {} seems to help (in contrast\n // to deleting all entries by their keys, as it is done within .teardown()\n // method below). Thus, for now we do this as a hotfix, and we also reset\n // build info to undefined, because ES module version not beeing reset\n // triggers an error on the subsequent test using the environment.\n // TODO: Look for a cleaner solution.\n require.cache = {};\n setBuildInfo(undefined, true);\n\n if (this.withSsr) await this.runSsr();\n this.global.REACT_UTILS_FORCE_CLIENT_SIDE = true;\n }\n\n async teardown(): Promise<void> {\n delete this.global.REACT_UTILS_FORCE_CLIENT_SIDE;\n\n // Resets module cache and @babel/register. Effectively this ensures that\n // the next time an instance of this environment is set up, all modules are\n // transformed by Babel from scratch, thus taking into account the latest\n // Babel config (which may change between different environment instances,\n // which does not seem to be taken into account by Babel / Node caches\n // automatically).\n Object.keys(require.cache).forEach((key) => {\n delete require.cache[key];\n });\n register.revert();\n await super.teardown();\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,10 +1,4 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = getGlobal;
7
- function getGlobal() {
1
+ export default function getGlobal() {
8
2
  return global;
9
3
  }
10
4
  //# sourceMappingURL=global.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"global.js","names":["getGlobal","global"],"sources":["../../../../../src/shared/utils/jest/global.ts"],"sourcesContent":["import type { IFs } from 'memfs';\nimport type { Configuration, StatsCompilation } from 'webpack';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface Window {\n ssrMarkup: string | undefined;\n ssrStatus: number | undefined;\n webpackConfig: Configuration | undefined;\n webpackOutputFs: IFs;\n webpackStats?: StatsCompilation;\n }\n}\n\nexport default function getGlobal(): Window {\n return global as unknown as Window;\n}\n"],"mappings":";;;;;;AAce,SAASA,SAASA,CAAA,EAAW;EAC1C,OAAOC,MAAM;AACf","ignoreList":[]}
1
+ {"version":3,"file":"global.js","names":["getGlobal","global"],"sources":["../../../../../src/shared/utils/jest/global.ts"],"sourcesContent":["import type { IFs } from 'memfs';\nimport type { Configuration, StatsCompilation } from 'webpack';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface Window {\n ssrMarkup: string | undefined;\n ssrStatus: number | undefined;\n webpackConfig: Configuration | undefined;\n webpackOutputFs: IFs;\n webpackStats?: StatsCompilation;\n }\n}\n\nexport default function getGlobal(): Window {\n return global as unknown as Window;\n}\n"],"mappings":"AAcA,eAAe,SAASA,SAASA,CAAA,EAAW;EAC1C,OAAOC,MAAM;AACf","ignoreList":[]}
@@ -1,41 +1,17 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- Object.defineProperty(exports, "act", {
8
- enumerable: true,
9
- get: function () {
10
- return _react.act;
11
- }
12
- });
13
- Object.defineProperty(exports, "getGlobal", {
14
- enumerable: true,
15
- get: function () {
16
- return _global.default;
17
- }
18
- });
19
- exports.getMockUuid = getMockUuid;
20
- exports.mockAxios = mockAxios;
21
- exports.mockClientSide = mockClientSide;
22
- exports.mockTimer = mockTimer;
23
- exports.mount = mount;
24
- exports.snapshot = snapshot;
25
- exports.unmockClientSide = unmockClientSide;
26
- var _mockdate = _interopRequireDefault(require("mockdate"));
27
- var _react = require("react");
28
- var _client = require("react-dom/client");
29
- var _react2 = require("@testing-library/react");
30
- var _global = _interopRequireDefault(require("./global"));
31
1
  /* global jest, document */
32
2
  /* eslint-disable import/no-extraneous-dependencies */
33
3
 
4
+ import mockdate from 'mockdate';
5
+ import { act } from 'react';
6
+ import { createRoot } from 'react-dom/client';
7
+ import { render } from '@testing-library/react';
8
+
34
9
  /**
35
10
  * An alias for [act(..)](https://reactjs.org/docs/test-utils.html#act)
36
11
  * from `react`.
37
12
  */
38
-
13
+ export { act };
14
+ export { default as getGlobal } from "./global.js";
39
15
  global.IS_REACT_ACT_ENVIRONMENT = true;
40
16
  const originalProcessVersions = process.versions;
41
17
 
@@ -43,7 +19,7 @@ const originalProcessVersions = process.versions;
43
19
  * Tricks **react-utils** into thinking the test is running within client-side
44
20
  * (browser) environment.
45
21
  */
46
- function mockClientSide() {
22
+ export function mockClientSide() {
47
23
  Object.defineProperty(process, 'versions', {
48
24
  value: undefined
49
25
  });
@@ -52,7 +28,7 @@ function mockClientSide() {
52
28
  /**
53
29
  * Reverts the effect of {@link module:JU.mockClientSide mockClientSide(..)}.
54
30
  */
55
- function unmockClientSide() {
31
+ export function unmockClientSide() {
56
32
  Object.defineProperty(process, 'versions', {
57
33
  value: originalProcessVersions,
58
34
  writable: false
@@ -65,11 +41,11 @@ function unmockClientSide() {
65
41
  * @param {number} seed
66
42
  * @return {string}
67
43
  */
68
- function getMockUuid(seed = 0) {
44
+ export function getMockUuid(seed = 0) {
69
45
  const x = seed.toString(16).padStart(32, '0');
70
46
  return `${x.slice(0, 8)}-${x.slice(8, 12)}-${x.slice(12, 16)}-${x.slice(16, 20)}-${x.slice(20)}`;
71
47
  }
72
- function mockAxios(handlers) {
48
+ export function mockAxios(handlers) {
73
49
  const axios = jest.requireActual('axios');
74
50
  axios.defaults.adapter = async config => {
75
51
  for (const handler of handlers) {
@@ -111,8 +87,8 @@ function mockAxios(handlers) {
111
87
  * @returns {Promise} Wait for this to "jump after" any async code which should
112
88
  * be executed because of the mock time movement.
113
89
  */
114
- async function mockTimer(time) {
115
- _mockdate.default.set(time + Date.now());
90
+ export async function mockTimer(time) {
91
+ mockdate.set(time + Date.now());
116
92
  await jest.advanceTimersByTimeAsync(time);
117
93
  }
118
94
  /**
@@ -121,7 +97,7 @@ async function mockTimer(time) {
121
97
  * @return Created container DOM element with destroy() function
122
98
  * attached.
123
99
  */
124
- function mount(scene) {
100
+ export function mount(scene) {
125
101
  let root;
126
102
  const element = document.createElement('div');
127
103
  document.body.appendChild(element);
@@ -130,7 +106,7 @@ function mount(scene) {
130
106
  // NOTE: As it seems @testing-library may reset this flag to false
131
107
  // when it is simulating user events.
132
108
  global.IS_REACT_ACT_ENVIRONMENT = true;
133
- (0, _react.act)(() => {
109
+ act(() => {
134
110
  root.unmount();
135
111
  });
136
112
  res.remove();
@@ -142,8 +118,8 @@ function mount(scene) {
142
118
  // NOTE: As it seems @testing-library may reset this flag to false
143
119
  // when it is simulating user events.
144
120
  global.IS_REACT_ACT_ENVIRONMENT = true;
145
- (0, _react.act)(() => {
146
- root = (0, _client.createRoot)(res);
121
+ act(() => {
122
+ root = createRoot(res);
147
123
  root.render(scene);
148
124
  });
149
125
  return res;
@@ -153,7 +129,7 @@ function mount(scene) {
153
129
  // across two objects, depending whether they are applicable to the sync, or async
154
130
  // versions of snapshot(), or both.
155
131
 
156
- function snapshot(element, options) {
132
+ export function snapshot(element, options) {
157
133
  let res;
158
134
 
159
135
  // TODO: Just adding async to the actor function breaks stuff, as it makes
@@ -162,8 +138,8 @@ function snapshot(element, options) {
162
138
  // to have a more complex typing to ensure it all works as intended in all
163
139
  // cases, and while being correctly enforced by TypeScript.
164
140
  // eslint-disable-next-line @typescript-eslint/promise-function-async
165
- const promise = (0, _react.act)(() => {
166
- res = (0, _react2.render)(element);
141
+ const promise = act(() => {
142
+ res = render(element);
167
143
  return options?.await;
168
144
  });
169
145
  if (res === undefined) throw Error('Render failed');
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_mockdate","_interopRequireDefault","require","_react","_client","_react2","_global","global","IS_REACT_ACT_ENVIRONMENT","originalProcessVersions","process","versions","mockClientSide","Object","defineProperty","value","undefined","unmockClientSide","writable","getMockUuid","seed","x","toString","padStart","slice","mockAxios","handlers","axios","jest","requireActual","defaults","adapter","config","handler","res","data","headers","status","statusText","console","warn","JSON","stringify","e","mockTimer","time","mockdate","set","Date","now","advanceTimersByTimeAsync","mount","scene","root","element","document","createElement","body","appendChild","destroy","act","unmount","remove","snapshot","expect","toMatchSnapshot","createRoot","render","options","promise","await","Error","Promise","resolve","then","nodes","asFragment","childNodes","length"],"sources":["../../../../../src/shared/utils/jest/index.ts"],"sourcesContent":["/* global jest, document */\n/* eslint-disable import/no-extraneous-dependencies */\n\nimport type {\n AxiosRequestConfig,\n AxiosResponse,\n AxiosStatic,\n InternalAxiosRequestConfig,\n} from 'axios';\n\nimport mockdate from 'mockdate';\nimport { type ReactElement, type ReactNode, act } from 'react';\nimport { type Root, createRoot } from 'react-dom/client';\n\nimport { type RenderResult, render } from '@testing-library/react';\n\n/**\n * An alias for [act(..)](https://reactjs.org/docs/test-utils.html#act)\n * from `react`.\n */\nexport { act };\n\nexport { default as getGlobal } from './global';\n\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\nconst originalProcessVersions = process.versions;\n\n/**\n * Tricks **react-utils** into thinking the test is running within client-side\n * (browser) environment.\n */\nexport function mockClientSide(): void {\n Object.defineProperty(process, 'versions', { value: undefined });\n}\n\n/**\n * Reverts the effect of {@link module:JU.mockClientSide mockClientSide(..)}.\n */\nexport function unmockClientSide(): void {\n Object.defineProperty(process, 'versions', {\n value: originalProcessVersions,\n writable: false,\n });\n}\n\n/**\n * Generates a mock UUID, or better said it determenistically transforms given\n * `seed` number into a UUID-formatted string.\n * @param {number} seed\n * @return {string}\n */\nexport function getMockUuid(seed = 0): string {\n const x = seed.toString(16).padStart(32, '0');\n return `${x.slice(0, 8)}-${x.slice(8, 12)}-${x.slice(12, 16)}-${x.slice(16, 20)}-${x.slice(20)}`;\n}\n\nexport type AxiosRequestHandlerT = (\n config: AxiosRequestConfig,\n) => Partial<AxiosResponse> | null | undefined;\n\nexport function mockAxios(handlers: AxiosRequestHandlerT[]): AxiosStatic {\n const axios: AxiosStatic = jest.requireActual('axios');\n\n axios.defaults.adapter = async (\n config: AxiosRequestConfig,\n ): Promise<AxiosResponse> => {\n for (const handler of handlers) {\n const res = handler(config);\n if (res) {\n return {\n config: config as InternalAxiosRequestConfig,\n data: null,\n headers: {},\n status: 200,\n statusText: 'OK',\n ...res,\n };\n }\n }\n\n // Fallback to the regular network request.\n let res: AxiosResponse;\n try {\n res = await axios({ ...config, adapter: ['xhr', 'http', 'fetch'] });\n // eslint-disable-next-line no-console\n console.warn(\n 'Network request has not been mocked for a test.\\n\\nConfig:\\n',\n config,\n '\\n\\nResult:\\n',\n JSON.stringify(res, null, 2),\n );\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Network request has not been mocked for a test, and failed.\\n\\nConfig:\\n',\n config,\n '\\n\\nError\\n',\n JSON.stringify(e, null, 2),\n );\n throw e;\n }\n\n return res;\n };\n\n return axios;\n}\n\n/**\n * Advances mock timers, and mock date by the specified time.\n * @param {number} time Time step [ms].\n * @returns {Promise} Wait for this to \"jump after\" any async code which should\n * be executed because of the mock time movement.\n */\nexport async function mockTimer(time: number): Promise<void> {\n mockdate.set(time + Date.now());\n await jest.advanceTimersByTimeAsync(time);\n}\n\nexport type MountedSceneT = HTMLElement & {\n destroy: () => void;\n snapshot: () => void;\n};\n\n/**\n * Mounts `scene` to the DOM, and returns the root scene element.\n * @param scene\n * @return Created container DOM element with destroy() function\n * attached.\n */\nexport function mount(scene: ReactNode): MountedSceneT {\n let root: Root;\n const element = document.createElement('div');\n document.body.appendChild(element);\n\n const res: MountedSceneT = (element as unknown) as MountedSceneT;\n res.destroy = () => {\n // NOTE: As it seems @testing-library may reset this flag to false\n // when it is simulating user events.\n global.IS_REACT_ACT_ENVIRONMENT = true;\n\n act(() => {\n root.unmount();\n });\n res.remove();\n };\n\n res.snapshot = () => {\n expect(res).toMatchSnapshot();\n };\n\n // NOTE: As it seems @testing-library may reset this flag to false\n // when it is simulating user events.\n global.IS_REACT_ACT_ENVIRONMENT = true;\n\n act(() => {\n root = createRoot(res);\n root.render(scene);\n });\n return res;\n}\n\n// NOTE: If in future we have additional options here, they should be distributed\n// across two objects, depending whether they are applicable to the sync, or async\n// versions of snapshot(), or both.\ntype AsyncSnapshotOptionsT = {\n await?: Promise<void>;\n};\n\nexport function snapshot(element: ReactElement): RenderResult;\n\nexport async function snapshot(\n element: ReactElement,\n options: AsyncSnapshotOptionsT,\n): Promise<RenderResult>;\n\nexport function snapshot(\n element: React.ReactElement,\n options?: AsyncSnapshotOptionsT,\n): Promise<RenderResult> | RenderResult {\n let res: RenderResult | undefined;\n\n // TODO: Just adding async to the actor function breaks stuff, as it makes\n // act() asynchronous no matter the `options.await` value, thus breaking all\n // calls that do not await for snapshot() result... thus... perhaps we need\n // to have a more complex typing to ensure it all works as intended in all\n // cases, and while being correctly enforced by TypeScript.\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n const promise = act(() => {\n res = render(element);\n return options?.await;\n });\n\n if (res === undefined) throw Error('Render failed');\n if (options?.await) {\n // BEWARE: Although `promise` is thenable (i.e. it has .then() method),\n // it is not an instance of proper Promise class, and returning it directly\n // breaks some async logic in Jest test or React test functions... thus, we\n // wrap it into Promise instance here.\n return new Promise((resolve) => {\n void promise.then(() => {\n // TODO: These lines are the same as the lines below for sync variant of\n // the function. We should split and reuse them in both places.\n const nodes = res!.asFragment().childNodes;\n expect(nodes.length > 1 ? [...nodes] : nodes[0]).toMatchSnapshot();\n resolve(res!);\n });\n });\n }\n\n const nodes = res.asFragment().childNodes;\n expect(nodes.length > 1 ? [...nodes] : nodes[0]).toMatchSnapshot();\n return res;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["mockdate","act","createRoot","render","default","getGlobal","global","IS_REACT_ACT_ENVIRONMENT","originalProcessVersions","process","versions","mockClientSide","Object","defineProperty","value","undefined","unmockClientSide","writable","getMockUuid","seed","x","toString","padStart","slice","mockAxios","handlers","axios","jest","requireActual","defaults","adapter","config","handler","res","data","headers","status","statusText","console","warn","JSON","stringify","e","mockTimer","time","set","Date","now","advanceTimersByTimeAsync","mount","scene","root","element","document","createElement","body","appendChild","destroy","unmount","remove","snapshot","expect","toMatchSnapshot","options","promise","await","Error","Promise","resolve","then","nodes","asFragment","childNodes","length"],"sources":["../../../../../src/shared/utils/jest/index.ts"],"sourcesContent":["/* global jest, document */\n/* eslint-disable import/no-extraneous-dependencies */\n\nimport type {\n AxiosRequestConfig,\n AxiosResponse,\n AxiosStatic,\n InternalAxiosRequestConfig,\n} from 'axios';\n\nimport mockdate from 'mockdate';\nimport { type ReactElement, type ReactNode, act } from 'react';\nimport { type Root, createRoot } from 'react-dom/client';\n\nimport { type RenderResult, render } from '@testing-library/react';\n\n/**\n * An alias for [act(..)](https://reactjs.org/docs/test-utils.html#act)\n * from `react`.\n */\nexport { act };\n\nexport { default as getGlobal } from './global';\n\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\nconst originalProcessVersions = process.versions;\n\n/**\n * Tricks **react-utils** into thinking the test is running within client-side\n * (browser) environment.\n */\nexport function mockClientSide(): void {\n Object.defineProperty(process, 'versions', { value: undefined });\n}\n\n/**\n * Reverts the effect of {@link module:JU.mockClientSide mockClientSide(..)}.\n */\nexport function unmockClientSide(): void {\n Object.defineProperty(process, 'versions', {\n value: originalProcessVersions,\n writable: false,\n });\n}\n\n/**\n * Generates a mock UUID, or better said it determenistically transforms given\n * `seed` number into a UUID-formatted string.\n * @param {number} seed\n * @return {string}\n */\nexport function getMockUuid(seed = 0): string {\n const x = seed.toString(16).padStart(32, '0');\n return `${x.slice(0, 8)}-${x.slice(8, 12)}-${x.slice(12, 16)}-${x.slice(16, 20)}-${x.slice(20)}`;\n}\n\nexport type AxiosRequestHandlerT = (\n config: AxiosRequestConfig,\n) => Partial<AxiosResponse> | null | undefined;\n\nexport function mockAxios(handlers: AxiosRequestHandlerT[]): AxiosStatic {\n const axios: AxiosStatic = jest.requireActual('axios');\n\n axios.defaults.adapter = async (\n config: AxiosRequestConfig,\n ): Promise<AxiosResponse> => {\n for (const handler of handlers) {\n const res = handler(config);\n if (res) {\n return {\n config: config as InternalAxiosRequestConfig,\n data: null,\n headers: {},\n status: 200,\n statusText: 'OK',\n ...res,\n };\n }\n }\n\n // Fallback to the regular network request.\n let res: AxiosResponse;\n try {\n res = await axios({ ...config, adapter: ['xhr', 'http', 'fetch'] });\n // eslint-disable-next-line no-console\n console.warn(\n 'Network request has not been mocked for a test.\\n\\nConfig:\\n',\n config,\n '\\n\\nResult:\\n',\n JSON.stringify(res, null, 2),\n );\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Network request has not been mocked for a test, and failed.\\n\\nConfig:\\n',\n config,\n '\\n\\nError\\n',\n JSON.stringify(e, null, 2),\n );\n throw e;\n }\n\n return res;\n };\n\n return axios;\n}\n\n/**\n * Advances mock timers, and mock date by the specified time.\n * @param {number} time Time step [ms].\n * @returns {Promise} Wait for this to \"jump after\" any async code which should\n * be executed because of the mock time movement.\n */\nexport async function mockTimer(time: number): Promise<void> {\n mockdate.set(time + Date.now());\n await jest.advanceTimersByTimeAsync(time);\n}\n\nexport type MountedSceneT = HTMLElement & {\n destroy: () => void;\n snapshot: () => void;\n};\n\n/**\n * Mounts `scene` to the DOM, and returns the root scene element.\n * @param scene\n * @return Created container DOM element with destroy() function\n * attached.\n */\nexport function mount(scene: ReactNode): MountedSceneT {\n let root: Root;\n const element = document.createElement('div');\n document.body.appendChild(element);\n\n const res: MountedSceneT = (element as unknown) as MountedSceneT;\n res.destroy = () => {\n // NOTE: As it seems @testing-library may reset this flag to false\n // when it is simulating user events.\n global.IS_REACT_ACT_ENVIRONMENT = true;\n\n act(() => {\n root.unmount();\n });\n res.remove();\n };\n\n res.snapshot = () => {\n expect(res).toMatchSnapshot();\n };\n\n // NOTE: As it seems @testing-library may reset this flag to false\n // when it is simulating user events.\n global.IS_REACT_ACT_ENVIRONMENT = true;\n\n act(() => {\n root = createRoot(res);\n root.render(scene);\n });\n return res;\n}\n\n// NOTE: If in future we have additional options here, they should be distributed\n// across two objects, depending whether they are applicable to the sync, or async\n// versions of snapshot(), or both.\ntype AsyncSnapshotOptionsT = {\n await?: Promise<void>;\n};\n\nexport function snapshot(element: ReactElement): RenderResult;\n\nexport async function snapshot(\n element: ReactElement,\n options: AsyncSnapshotOptionsT,\n): Promise<RenderResult>;\n\nexport function snapshot(\n element: React.ReactElement,\n options?: AsyncSnapshotOptionsT,\n): Promise<RenderResult> | RenderResult {\n let res: RenderResult | undefined;\n\n // TODO: Just adding async to the actor function breaks stuff, as it makes\n // act() asynchronous no matter the `options.await` value, thus breaking all\n // calls that do not await for snapshot() result... thus... perhaps we need\n // to have a more complex typing to ensure it all works as intended in all\n // cases, and while being correctly enforced by TypeScript.\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n const promise = act(() => {\n res = render(element);\n return options?.await;\n });\n\n if (res === undefined) throw Error('Render failed');\n if (options?.await) {\n // BEWARE: Although `promise` is thenable (i.e. it has .then() method),\n // it is not an instance of proper Promise class, and returning it directly\n // breaks some async logic in Jest test or React test functions... thus, we\n // wrap it into Promise instance here.\n return new Promise((resolve) => {\n void promise.then(() => {\n // TODO: These lines are the same as the lines below for sync variant of\n // the function. We should split and reuse them in both places.\n const nodes = res!.asFragment().childNodes;\n expect(nodes.length > 1 ? [...nodes] : nodes[0]).toMatchSnapshot();\n resolve(res!);\n });\n });\n }\n\n const nodes = res.asFragment().childNodes;\n expect(nodes.length > 1 ? [...nodes] : nodes[0]).toMatchSnapshot();\n return res;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,29 +1,23 @@
1
- "use strict";
1
+ /* global document */
2
2
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.bookStyleSheets = bookStyleSheets;
7
- exports.default = splitComponent;
8
- exports.freeStyleSheets = freeStyleSheets;
9
- var _react = require("react");
10
- var _jsUtils = require("@dr.pogodin/js-utils");
11
- var _globalState = require("./globalState");
12
- var _isomorphy = require("./isomorphy");
13
- var _jsxRuntime = require("react/jsx-runtime");
14
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /* global document */
3
+ import { Suspense, lazy, useInsertionEffect } from 'react';
4
+ import { Barrier } from '@dr.pogodin/js-utils';
5
+ import { getSsrContext } from "./globalState.js";
6
+ import { IS_CLIENT_SIDE, IS_SERVER_SIDE, getBuildInfo } from "./isomorphy/index.js";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
15
8
  function getClientChunkGroups() {
16
- if (!_isomorphy.IS_CLIENT_SIDE) return undefined;
9
+ if (!IS_CLIENT_SIDE) return undefined;
17
10
  return (async () => {
18
11
  const {
19
12
  default: getInj
20
- } = await Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "react-utils-client-side-code" */"../../client/getInj")));
21
- return getInj().CHUNK_GROUPS ?? {};
13
+ } = await import(/* webpackChunkName: "react-utils-client-side-code" */"../../client/getInj");
14
+ const inj = await getInj();
15
+ return inj.CHUNK_GROUPS ?? {};
22
16
  })();
23
17
  }
24
18
  const refCounts = {};
25
19
  function getPublicPath() {
26
- return (0, _isomorphy.getBuildInfo)().publicPath;
20
+ return getBuildInfo().publicPath;
27
21
  }
28
22
 
29
23
  /**
@@ -47,7 +41,7 @@ function bookStyleSheet(name, loadedSheets, refCount) {
47
41
  link.setAttribute('href', path);
48
42
  document.head.appendChild(link);
49
43
  }
50
- res = new _jsUtils.Barrier();
44
+ res = new Barrier();
51
45
  link.addEventListener('load', () => {
52
46
  if (!res) throw Error('Internal error');
53
47
  void res.resolve();
@@ -94,7 +88,7 @@ function assertChunkName(chunkName, chunkGroups) {
94
88
  * @return Resolves once all pending stylesheets, necessary for
95
89
  * the chunk, are either loaded, or failed to load.
96
90
  */
97
- async function bookStyleSheets(chunkName, chunkGroups, refCount) {
91
+ export async function bookStyleSheets(chunkName, chunkGroups, refCount) {
98
92
  const promises = [];
99
93
  const assets = chunkGroups[chunkName];
100
94
  if (!assets) return Promise.resolve();
@@ -115,7 +109,7 @@ async function bookStyleSheets(chunkName, chunkGroups, refCount) {
115
109
  * the reference counter).
116
110
  * @param {string} chunkName
117
111
  */
118
- function freeStyleSheets(chunkName, chunkGroups) {
112
+ export function freeStyleSheets(chunkName, chunkGroups) {
119
113
  const assets = chunkGroups[chunkName];
120
114
  if (!assets) return;
121
115
  for (const asset of assets) {
@@ -144,7 +138,7 @@ const usedChunkNames = new Set();
144
138
  * @param {React.Element} [options.placeholder]
145
139
  * @return {React.ElementType}
146
140
  */
147
- function splitComponent({
141
+ export default function splitComponent({
148
142
  chunkName,
149
143
  getComponent,
150
144
  placeholder
@@ -153,11 +147,11 @@ function splitComponent({
153
147
  if (usedChunkNames.has(chunkName)) {
154
148
  throw Error(`Repeated splitComponent() call for the chunk "${chunkName}"`);
155
149
  } else usedChunkNames.add(chunkName);
156
- const LazyComponent = /*#__PURE__*/(0, _react.lazy)(async () => {
150
+ const LazyComponent = /*#__PURE__*/lazy(async () => {
157
151
  const clientChunkGroups = await getClientChunkGroups();
158
152
 
159
153
  // On the client side we can check right away if the chunk name is known.
160
- if (_isomorphy.IS_CLIENT_SIDE) {
154
+ if (IS_CLIENT_SIDE) {
161
155
  if (!clientChunkGroups) throw Error('Internal error');
162
156
  assertChunkName(chunkName, clientChunkGroups);
163
157
  }
@@ -167,7 +161,7 @@ function splitComponent({
167
161
  // This pre-loads necessary stylesheets prior to the first mount of
168
162
  // the component (the lazy load function is executed by React one at
169
163
  // the frist mount).
170
- if (_isomorphy.IS_CLIENT_SIDE) {
164
+ if (IS_CLIENT_SIDE) {
171
165
  if (!clientChunkGroups) throw Error('Internal error');
172
166
  await bookStyleSheets(chunkName, clientChunkGroups, false);
173
167
  }
@@ -178,25 +172,25 @@ function splitComponent({
178
172
  }) => {
179
173
  // On the server side we'll assert the chunk name here,
180
174
  // and also push it to the SSR chunks array.
181
- if (_isomorphy.IS_SERVER_SIDE) {
175
+ if (IS_SERVER_SIDE) {
182
176
  const {
183
177
  chunkGroups,
184
178
  chunks
185
- } = (0, _globalState.getSsrContext)();
179
+ } = getSsrContext();
186
180
  assertChunkName(chunkName, chunkGroups);
187
181
  if (!chunks.includes(chunkName)) chunks.push(chunkName);
188
182
  }
189
183
 
190
184
  // This takes care about stylesheets management every time an instance of
191
185
  // this component is mounted / unmounted.
192
- (0, _react.useInsertionEffect)(() => {
186
+ useInsertionEffect(() => {
193
187
  if (!clientChunkGroups) throw Error('Internal error');
194
188
  void bookStyleSheets(chunkName, clientChunkGroups, true);
195
189
  return () => {
196
190
  freeStyleSheets(chunkName, clientChunkGroups);
197
191
  };
198
192
  }, []);
199
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component
193
+ return /*#__PURE__*/_jsx(Component
200
194
  // eslint-disable-next-line react/jsx-props-no-spreading
201
195
  , {
202
196
  ...rest,
@@ -211,9 +205,9 @@ function splitComponent({
211
205
  const CodeSplit = ({
212
206
  children,
213
207
  ...rest
214
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Suspense, {
208
+ }) => /*#__PURE__*/_jsx(Suspense, {
215
209
  fallback: placeholder,
216
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LazyComponent
210
+ children: /*#__PURE__*/_jsx(LazyComponent
217
211
  // eslint-disable-next-line react/jsx-props-no-spreading
218
212
  , {
219
213
  ...rest,