@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
@@ -2,6 +2,8 @@
2
2
  * ExpressJS middleware for server-side rendering of a ReactJS app.
3
3
  */
4
4
 
5
+ import { Buffer } from 'node:buffer';
6
+ import { type Cipheriv, createCipheriv, randomBytes } from 'node:crypto';
5
7
  import fs from 'node:fs';
6
8
  import path from 'node:path';
7
9
  import { Writable } from 'node:stream';
@@ -15,16 +17,14 @@ import winston from 'winston';
15
17
  import { GlobalStateProvider, SsrContext } from '@dr.pogodin/react-global-state';
16
18
  import { timer } from '@dr.pogodin/js-utils';
17
19
 
18
- import clone from 'lodash/clone';
19
- import cloneDeep from 'lodash/cloneDeep';
20
- import defaults from 'lodash/defaults';
21
- import get from 'lodash/get';
22
- import isString from 'lodash/isString';
23
- import mapValues from 'lodash/mapValues';
24
- import omit from 'lodash/omit';
20
+ import {
21
+ cloneDeep,
22
+ defaults,
23
+ get,
24
+ mapValues,
25
+ } from 'lodash-es';
25
26
 
26
27
  import config from 'config';
27
- import forge from 'node-forge';
28
28
 
29
29
  import { prerenderToNodeStream } from 'react-dom/static';
30
30
  import { type HelmetDataContext, HelmetProvider } from '@dr.pogodin/react-helmet';
@@ -36,7 +36,9 @@ import type { ChunkGroupsT, SsrContextT } from 'utils/globalState';
36
36
 
37
37
  import Cache from './Cache';
38
38
 
39
- const sanitizedConfig = omit(config, 'SECRET');
39
+ // @ts-expect-error "Property 'SECRET' does not exist on type 'IConfig'."
40
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
+ const { SECRET, ...sanitizedConfig } = config;
40
42
 
41
43
  // Note: These type definitions for logger are copied from Winston logger,
42
44
  // then simplified to make it easier to fit an alternative logger into this
@@ -133,26 +135,15 @@ function readChunkGroupsJson(buildDir: string) {
133
135
 
134
136
  /**
135
137
  * Prepares a new Cipher for data encryption.
136
- * @param key Encryption key (32-bit random key is expected, see
137
- * node-forge documentation, in case of doubts).
138
- * @return Resolves to the object with two fields:
138
+ * @param key Encryption key (32-bit random, Base64-encoded key is expected).
139
+ * @return Returns a tuple of:
139
140
  * 1. cipher - a new Cipher, ready for encryption;
140
141
  * 2. iv - initial vector used by the cipher.
141
142
  */
142
- async function prepareCipher(key: string): Promise<{
143
- cipher: forge.cipher.BlockCipher;
144
- iv: string;
145
- }> {
146
- return new Promise((resolve, reject) => {
147
- forge.random.getBytes(32, (err, iv) => {
148
- if (err) reject(err);
149
- else {
150
- const cipher = forge.cipher.createCipher('AES-CBC', key);
151
- cipher.start({ iv });
152
- resolve({ cipher, iv });
153
- }
154
- });
155
- });
143
+ function prepareCipher(key: string): [cipher: Cipheriv, iv: Buffer] {
144
+ const iv = randomBytes(16);
145
+ const cipher = createCipheriv('AES-256-CBC', Buffer.from(key, 'base64'), iv);
146
+ return [cipher, iv];
156
147
  }
157
148
 
158
149
  /**
@@ -196,7 +187,7 @@ function groupExtraScripts(scripts: Array<string | ScriptT> = []) {
196
187
  [SCRIPT_LOCATIONS.HEAD_OPEN]: '',
197
188
  };
198
189
  for (const script of scripts) {
199
- if (isString(script)) {
190
+ if (typeof script === 'string') {
200
191
  if (script) res[SCRIPT_LOCATIONS.DEFAULT] += script;
201
192
  } else if (script.code) {
202
193
  if (script.location in res) res[script.location] += script.code;
@@ -312,7 +303,7 @@ export default function factory(
312
303
  webpackConfig: Configuration,
313
304
  options: OptionsT,
314
305
  ): RequestHandler {
315
- const ops: OptionsT = defaults(clone(options), {
306
+ const ops: OptionsT = defaults({ ...options }, {
316
307
  beforeRender: async () => Promise.resolve({}),
317
308
  maxSsrRounds: 10,
318
309
  ssrTimeout: 1000,
@@ -400,21 +391,9 @@ export default function factory(
400
391
  }
401
392
 
402
393
  const brr = ops.beforeRender!(req, sanitizedConfig as unknown as ConfigT);
394
+ const { configToInject, extraScripts, initialState } = await brr;
403
395
 
404
- const [{
405
- configToInject,
406
- extraScripts,
407
- initialState,
408
- }, {
409
- cipher,
410
- iv,
411
- }] = await Promise.all([
412
- // NOTE: Written this way to avoid triggering the "await-thenable"
413
- // ESLint rule.
414
- brr instanceof Promise ? brr : Promise.resolve(brr),
415
-
416
- prepareCipher(buildInfo.key),
417
- ]);
396
+ const [cipher, iv] = prepareCipher(buildInfo.key);
418
397
 
419
398
  let helmet: HelmetDataContext['helmet'];
420
399
 
@@ -553,9 +532,12 @@ export default function factory(
553
532
  ignoreFunction: true,
554
533
  unsafe: true,
555
534
  });
556
- cipher.update(forge.util.createBuffer(payload, 'utf8'));
557
- cipher.finish();
558
- const INJ = forge.util.encode64(`${iv}${cipher.output.data}`);
535
+
536
+ const INJ = Buffer.concat([
537
+ iv,
538
+ cipher.update(payload, 'utf8'),
539
+ cipher.final(),
540
+ ]).toString('base64');
559
541
 
560
542
  const chunkSet = new Set<string>();
561
543
 
@@ -5,9 +5,7 @@
5
5
  import { sep } from 'node:path';
6
6
  import { pathToFileURL } from 'node:url';
7
7
 
8
- import cloneDeep from 'lodash/cloneDeep';
9
- import mapValues from 'lodash/mapValues';
10
- import pick from 'lodash/pick';
8
+ import { cloneDeep, mapValues, pick } from 'lodash-es';
11
9
 
12
10
  import compression from 'compression';
13
11
  import cookieParser from 'cookie-parser';
@@ -250,7 +248,7 @@ export default async function factory(
250
248
  } as Location;
251
249
  }
252
250
 
253
- const { webpack } = await import(/* webpackChunkName: "server-side-code" */ 'webpack');
251
+ const { default: webpack } = await import(/* webpackChunkName: "server-side-code" */ 'webpack');
254
252
 
255
253
  const { default: webpackDevMiddleware } = await import(
256
254
  /* webpackChunkName: "server-side-code" */ 'webpack-dev-middleware'
@@ -7,7 +7,7 @@ import {
7
7
  useRef,
8
8
  } from 'react';
9
9
 
10
- import ReactDom from 'react-dom';
10
+ import { createPortal } from 'react-dom';
11
11
  import themed, { type Theme } from '@dr.pogodin/react-themes';
12
12
 
13
13
  import baseTheme from './base-theme.scss';
@@ -96,7 +96,7 @@ const BaseModal: FunctionComponent<PropsT> = ({
96
96
  />
97
97
  ), []);
98
98
 
99
- return ReactDom.createPortal(
99
+ return createPortal(
100
100
  (
101
101
  <div>
102
102
  {focusLast}
@@ -7,17 +7,53 @@ import clientGetInj from '../../client/getInj';
7
7
  import { IS_CLIENT_SIDE } from './isomorphy/environment-check';
8
8
  import { requireWeak } from './webpack';
9
9
 
10
- // TODO: The internal type casting is somewhat messed up here,
11
- // to be corrected later.
12
- const config: Record<string, unknown> = (
13
- IS_CLIENT_SIDE ? clientGetInj().CONFIG : requireWeak('config')
14
- ) as (Record<string, unknown> | undefined) ?? ({} as Record<string, unknown>);
15
-
16
- // The safeguard for "document" is necessary because in non-Node environments,
17
- // like React Native, IS_CLIENT_SIDE is "true", however "document" and a bunch
18
- // of other browser-world features are not available.
19
- if (IS_CLIENT_SIDE && typeof document !== 'undefined') {
20
- config.CSRF = parse(document.cookie).csrfToken;
10
+ type ConfigT = Record<string, unknown>;
11
+
12
+ let config: ConfigT | Promise<ConfigT> | undefined;
13
+
14
+ /**
15
+ * Injects CSRF token into config (on client-side only).
16
+ *
17
+ * BEWARE: It mutates the argument, and also returns it as the result,
18
+ * for chaining.
19
+ */
20
+ function injectCsrfToken(cfg: ConfigT): ConfigT {
21
+ // The safeguard for "document" is necessary because in non-Node environments,
22
+ // like React Native, IS_CLIENT_SIDE is "true", however "document" and a bunch
23
+ // of other browser-world features are not available.
24
+ if (IS_CLIENT_SIDE && typeof document !== 'undefined') {
25
+ // eslint-disable-next-line no-param-reassign
26
+ cfg.CSRF = parse(document.cookie).csrfToken;
27
+ }
28
+
29
+ return cfg;
21
30
  }
22
31
 
23
- export default config;
32
+ export function getConfig(sync: true): ConfigT;
33
+
34
+ export function getConfig(sync?: boolean): ConfigT | Promise<ConfigT>;
35
+
36
+ export function getConfig(sync?: boolean): ConfigT | Promise<ConfigT> {
37
+ if (!config) {
38
+ if (IS_CLIENT_SIDE) {
39
+ const inj = clientGetInj();
40
+ config = inj instanceof Promise
41
+ ? inj.then((injection) => {
42
+ const res = injectCsrfToken(injection.CONFIG ?? {});
43
+ config = res;
44
+ return res;
45
+ })
46
+ : injectCsrfToken(inj.CONFIG ?? {});
47
+ } else {
48
+ const weak = requireWeak<ConfigT>('config');
49
+ if (!weak) throw Error('Internal error');
50
+ config = weak;
51
+ }
52
+ }
53
+
54
+ if (sync && (config instanceof Promise)) {
55
+ throw Error('The config is not available yet');
56
+ }
57
+
58
+ return config;
59
+ }
@@ -5,7 +5,7 @@ import themedImpl, {
5
5
  ThemeProvider,
6
6
  } from '@dr.pogodin/react-themes';
7
7
 
8
- import config from './config';
8
+ import { getConfig } from './config';
9
9
  import * as isomorphy from './isomorphy';
10
10
  import time from './time';
11
11
  import * as webpack from './webpack';
@@ -36,7 +36,7 @@ themed.PRIORITY = PRIORITY;
36
36
 
37
37
  export {
38
38
  type Theme,
39
- config,
39
+ getConfig,
40
40
  isomorphy,
41
41
  themed,
42
42
  ThemeProvider,
@@ -20,8 +20,7 @@ import path from 'node:path';
20
20
 
21
21
  import type { Request, Response } from 'express';
22
22
 
23
- import defaults from 'lodash/defaults';
24
- import set from 'lodash/set';
23
+ import { defaults, set } from 'lodash-es';
25
24
 
26
25
  import type { ReactNode } from 'react';
27
26
 
@@ -25,7 +25,9 @@ function getClientChunkGroups(): Promise<ChunkGroupsT> | undefined {
25
25
 
26
26
  return (async () => {
27
27
  const { default: getInj } = await import(/* webpackChunkName: "react-utils-client-side-code" */ '../../client/getInj');
28
- return getInj().CHUNK_GROUPS ?? {};
28
+
29
+ const inj = await getInj();
30
+ return inj.CHUNK_GROUPS ?? {};
29
31
  })();
30
32
  }
31
33
 
@@ -171,6 +173,16 @@ type ComponentOrModule<PropsT> = ComponentType<PropsT> | {
171
173
  default: ComponentType<PropsT>;
172
174
  };
173
175
 
176
+ type GenericComponentPropsT = {
177
+ children?: ReactNode;
178
+ ref?: RefObject<unknown>;
179
+
180
+ // NOTE: This is necessary, as without it this type (with only optional
181
+ // fields) will be conisdered as "weak" by TypeScript, and it will be
182
+ // a error to assign to it any type that does not use "children", or "ref".
183
+ [propName: string]: unknown;
184
+ };
185
+
174
186
  /**
175
187
  * Given an async component retrieval function `getComponent()` it creates
176
188
  * a special "code split" component, which uses <Suspense> to asynchronously
@@ -182,7 +194,7 @@ type ComponentOrModule<PropsT> = ComponentType<PropsT> | {
182
194
  * @return {React.ElementType}
183
195
  */
184
196
  export default function splitComponent<
185
- ComponentPropsT extends { children?: ReactNode; ref?: RefObject<unknown> },
197
+ ComponentPropsT extends GenericComponentPropsT,
186
198
  >({
187
199
  chunkName,
188
200
  getComponent,
@@ -1,6 +1,9 @@
1
1
  import type PathNS from 'node:path';
2
2
 
3
- import { IS_CLIENT_SIDE } from './isomorphy';
3
+ // eslint-disable-next-line import/enforce-node-protocol-usage
4
+ import { createRequire } from 'module';
5
+
6
+ import { IS_CLIENT_SIDE, IS_SERVER_SIDE } from './isomorphy';
4
7
 
5
8
  type RequireWeakOptionsT = {
6
9
  basePath?: string;
@@ -10,6 +13,10 @@ type RequireWeakResT<T> = T extends { default: infer D }
10
13
  ? (D extends null | undefined ? T : D & Omit<T, 'default'>)
11
14
  : T;
12
15
 
16
+ let require: ((url: string) => unknown) | undefined;
17
+
18
+ if (IS_SERVER_SIDE) require = createRequire(import.meta.url);
19
+
13
20
  /**
14
21
  * Requires the specified module without including it into the bundle during
15
22
  * Webpack build.
@@ -36,14 +43,12 @@ export function requireWeak<T extends object>(
36
43
  ({ basePath } = ops);
37
44
  }
38
45
 
39
- // eslint-disable-next-line no-eval
40
- const req = eval('require') as (path: string) => unknown;
41
-
42
46
  // eslint-disable-next-line @typescript-eslint/unbound-method
43
- const { resolve } = req('path') as typeof PathNS;
47
+ const { resolve } = require!('node:path') as typeof PathNS;
44
48
 
45
49
  const path = basePath ? resolve(basePath, modulePath) : modulePath;
46
- const module = req(path) as T;
50
+
51
+ const module = require!(path) as T;
47
52
 
48
53
  if (!('default' in module) || !module.default) return module as RequireWeakResT<T>;
49
54
 
@@ -53,8 +58,9 @@ export function requireWeak<T extends object>(
53
58
 
54
59
  Object.entries(named).forEach(([name, value]) => {
55
60
  const assigned = res[name as keyof RequireWeakResT<T>];
56
- if (assigned) (res[name as keyof RequireWeakResT<T>] as unknown) = value;
57
- else if (assigned !== value) {
61
+ if (assigned === undefined) {
62
+ (res[name as keyof RequireWeakResT<T>] as unknown) = value;
63
+ } else if (assigned !== value) {
58
64
  throw Error('Conflict between default and named exports');
59
65
  }
60
66
  });
package/types.d.ts CHANGED
@@ -4,6 +4,7 @@ declare var IS_REACT_ACT_ENVIRONMENT: boolean | undefined;
4
4
  declare var REACT_UTILS_WEBPACK_BUNDLE: boolean | undefined;
5
5
  declare var REACT_UTILS_LIBRARY_LOADED: boolean | undefined;
6
6
  declare var REACT_UTILS_FORCE_CLIENT_SIDE: boolean | undefined;
7
+ declare var SCENE_INIT_PROMISE: Promise<void> | undefined;
7
8
  /* eslint-enable no-var */
8
9
 
9
10
  declare module '@babel/register/experimental-worker' {
@@ -19,12 +20,6 @@ declare module '@babel/register/experimental-worker' {
19
20
  export default register;
20
21
  }
21
22
 
22
- declare module 'node-forge/lib/forge' {
23
- import F from 'node-forge';
24
-
25
- export default F;
26
- }
27
-
28
23
  declare module '*.png' {
29
24
  const path: string;
30
25
  export default path;