@dr.pogodin/react-utils 1.46.2 → 1.47.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/babel.config.js +1 -0
  2. package/babel.libweb.config.js +16 -0
  3. package/babel.module.config.js +11 -0
  4. package/bin/build.js +21 -11
  5. package/bin/setup.js +11 -9
  6. package/build/development/client/getInj.js +57 -44
  7. package/build/development/client/getInj.js.map +1 -1
  8. package/build/development/client/index.js +15 -21
  9. package/build/development/client/index.js.map +1 -1
  10. package/build/development/client/init.js +2 -6
  11. package/build/development/client/init.js.map +1 -1
  12. package/build/development/index.js +3 -177
  13. package/build/development/index.js.map +1 -1
  14. package/build/development/server/Cache.js +1 -8
  15. package/build/development/server/Cache.js.map +1 -1
  16. package/build/development/server/index.js +22 -45
  17. package/build/development/server/index.js.map +1 -1
  18. package/build/development/server/renderer.js +84 -86
  19. package/build/development/server/renderer.js.map +1 -1
  20. package/build/development/server/server.js +58 -60
  21. package/build/development/server/server.js.map +1 -1
  22. package/build/development/server/utils/errors.js +8 -31
  23. package/build/development/server/utils/errors.js.map +1 -1
  24. package/build/development/server/utils/index.js +2 -9
  25. package/build/development/server/utils/index.js.map +1 -1
  26. package/build/development/shared/components/Button/index.js +15 -22
  27. package/build/development/shared/components/Button/index.js.map +1 -1
  28. package/build/development/shared/components/Checkbox/index.js +14 -21
  29. package/build/development/shared/components/Checkbox/index.js.map +1 -1
  30. package/build/development/shared/components/GenericLink/index.js +9 -11
  31. package/build/development/shared/components/GenericLink/index.js.map +1 -1
  32. package/build/development/shared/components/Input/index.js +21 -27
  33. package/build/development/shared/components/Input/index.js.map +1 -1
  34. package/build/development/shared/components/Link.js +6 -13
  35. package/build/development/shared/components/Link.js.map +1 -1
  36. package/build/development/shared/components/Modal/index.js +24 -28
  37. package/build/development/shared/components/Modal/index.js.map +1 -1
  38. package/build/development/shared/components/NavLink.js +6 -13
  39. package/build/development/shared/components/NavLink.js.map +1 -1
  40. package/build/development/shared/components/PageLayout/index.js +13 -20
  41. package/build/development/shared/components/PageLayout/index.js.map +1 -1
  42. package/build/development/shared/components/TextArea/index.js +28 -31
  43. package/build/development/shared/components/TextArea/index.js.map +1 -1
  44. package/build/development/shared/components/Throbber/index.js +13 -20
  45. package/build/development/shared/components/Throbber/index.js.map +1 -1
  46. package/build/development/shared/components/WithTooltip/Tooltip.js +13 -18
  47. package/build/development/shared/components/WithTooltip/Tooltip.js.map +1 -1
  48. package/build/development/shared/components/WithTooltip/index.js +23 -30
  49. package/build/development/shared/components/WithTooltip/index.js.map +1 -1
  50. package/build/development/shared/components/YouTubeVideo/index.js +19 -26
  51. package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
  52. package/build/development/shared/components/index.js +16 -130
  53. package/build/development/shared/components/index.js.map +1 -1
  54. package/build/development/shared/components/selectors/CustomDropdown/Options/index.js +19 -20
  55. package/build/development/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
  56. package/build/development/shared/components/selectors/CustomDropdown/index.js +35 -39
  57. package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
  58. package/build/development/shared/components/selectors/NativeDropdown/index.js +31 -31
  59. package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
  60. package/build/development/shared/components/selectors/Switch/index.js +19 -24
  61. package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
  62. package/build/development/shared/components/selectors/common.js +1 -7
  63. package/build/development/shared/components/selectors/common.js.map +1 -1
  64. package/build/development/shared/components/selectors/index.js +3 -27
  65. package/build/development/shared/components/selectors/index.js.map +1 -1
  66. package/build/development/shared/utils/config.js +40 -21
  67. package/build/development/shared/utils/config.js.map +1 -1
  68. package/build/development/shared/utils/globalState.js +3 -8
  69. package/build/development/shared/utils/globalState.js.map +1 -1
  70. package/build/development/shared/utils/index.js +12 -89
  71. package/build/development/shared/utils/index.js.map +1 -1
  72. package/build/development/shared/utils/isomorphy/buildInfo.js +2 -9
  73. package/build/development/shared/utils/isomorphy/buildInfo.js.map +1 -1
  74. package/build/development/shared/utils/isomorphy/environment-check.js +2 -8
  75. package/build/development/shared/utils/isomorphy/environment-check.js.map +1 -1
  76. package/build/development/shared/utils/isomorphy/index.js +7 -32
  77. package/build/development/shared/utils/isomorphy/index.js.map +1 -1
  78. package/build/development/shared/utils/jest/E2eSsrEnv.js +34 -37
  79. package/build/development/shared/utils/jest/E2eSsrEnv.js.map +1 -1
  80. package/build/development/shared/utils/jest/global.js +1 -7
  81. package/build/development/shared/utils/jest/global.js.map +1 -1
  82. package/build/development/shared/utils/jest/index.js +20 -44
  83. package/build/development/shared/utils/jest/index.js.map +1 -1
  84. package/build/development/shared/utils/splitComponent.js +54 -45
  85. package/build/development/shared/utils/splitComponent.js.map +1 -1
  86. package/build/development/shared/utils/time.js +22 -31
  87. package/build/development/shared/utils/time.js.map +1 -1
  88. package/build/development/shared/utils/webpack.js +17 -16
  89. package/build/development/shared/utils/webpack.js.map +1 -1
  90. package/build/production/client/getInj.js +13 -11
  91. package/build/production/client/getInj.js.map +1 -1
  92. package/build/production/client/index.js +3 -3
  93. package/build/production/client/index.js.map +1 -1
  94. package/build/production/client/init.js +2 -2
  95. package/build/production/client/init.js.map +1 -1
  96. package/build/production/index.js +2 -3
  97. package/build/production/index.js.map +1 -1
  98. package/build/production/server/Cache.js +3 -3
  99. package/build/production/server/Cache.js.map +1 -1
  100. package/build/production/server/index.js +8 -8
  101. package/build/production/server/index.js.map +1 -1
  102. package/build/production/server/renderer.js +24 -25
  103. package/build/production/server/renderer.js.map +1 -1
  104. package/build/production/server/server.js +9 -11
  105. package/build/production/server/server.js.map +1 -1
  106. package/build/production/server/utils/errors.js +9 -9
  107. package/build/production/server/utils/errors.js.map +1 -1
  108. package/build/production/server/utils/index.js +2 -1
  109. package/build/production/server/utils/index.js.map +1 -1
  110. package/build/production/shared/components/Button/index.js +4 -4
  111. package/build/production/shared/components/Button/index.js.map +1 -1
  112. package/build/production/shared/components/Checkbox/index.js +1 -1
  113. package/build/production/shared/components/Checkbox/index.js.map +1 -1
  114. package/build/production/shared/components/GenericLink/index.js +4 -4
  115. package/build/production/shared/components/GenericLink/index.js.map +1 -1
  116. package/build/production/shared/components/Input/index.js +5 -5
  117. package/build/production/shared/components/Input/index.js.map +1 -1
  118. package/build/production/shared/components/Link.js +3 -3
  119. package/build/production/shared/components/Link.js.map +1 -1
  120. package/build/production/shared/components/Modal/index.js +7 -7
  121. package/build/production/shared/components/Modal/index.js.map +1 -1
  122. package/build/production/shared/components/NavLink.js +2 -2
  123. package/build/production/shared/components/NavLink.js.map +1 -1
  124. package/build/production/shared/components/PageLayout/index.js +2 -2
  125. package/build/production/shared/components/PageLayout/index.js.map +1 -1
  126. package/build/production/shared/components/TextArea/index.js +5 -5
  127. package/build/production/shared/components/TextArea/index.js.map +1 -1
  128. package/build/production/shared/components/Throbber/index.js +2 -2
  129. package/build/production/shared/components/Throbber/index.js.map +1 -1
  130. package/build/production/shared/components/WithTooltip/Tooltip.js +4 -4
  131. package/build/production/shared/components/WithTooltip/Tooltip.js.map +1 -1
  132. package/build/production/shared/components/WithTooltip/index.js +4 -4
  133. package/build/production/shared/components/WithTooltip/index.js.map +1 -1
  134. package/build/production/shared/components/YouTubeVideo/index.js +4 -4
  135. package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
  136. package/build/production/shared/components/index.js +3 -1
  137. package/build/production/shared/components/index.js.map +1 -1
  138. package/build/production/shared/components/selectors/CustomDropdown/Options/index.js +2 -2
  139. package/build/production/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
  140. package/build/production/shared/components/selectors/CustomDropdown/index.js +2 -2
  141. package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -1
  142. package/build/production/shared/components/selectors/NativeDropdown/index.js +4 -4
  143. package/build/production/shared/components/selectors/NativeDropdown/index.js.map +1 -1
  144. package/build/production/shared/components/selectors/Switch/index.js +1 -1
  145. package/build/production/shared/components/selectors/Switch/index.js.map +1 -1
  146. package/build/production/shared/components/selectors/common.js +2 -2
  147. package/build/production/shared/components/selectors/common.js.map +1 -1
  148. package/build/production/shared/components/selectors/index.js +1 -1
  149. package/build/production/shared/components/selectors/index.js.map +1 -1
  150. package/build/production/shared/utils/config.js +8 -6
  151. package/build/production/shared/utils/config.js.map +1 -1
  152. package/build/production/shared/utils/globalState.js +2 -2
  153. package/build/production/shared/utils/globalState.js.map +1 -1
  154. package/build/production/shared/utils/index.js +1 -1
  155. package/build/production/shared/utils/index.js.map +1 -1
  156. package/build/production/shared/utils/isomorphy/buildInfo.js +3 -3
  157. package/build/production/shared/utils/isomorphy/buildInfo.js.map +1 -1
  158. package/build/production/shared/utils/isomorphy/environment-check.js +3 -3
  159. package/build/production/shared/utils/isomorphy/environment-check.js.map +1 -1
  160. package/build/production/shared/utils/isomorphy/index.js +4 -4
  161. package/build/production/shared/utils/isomorphy/index.js.map +1 -1
  162. package/build/production/shared/utils/jest/E2eSsrEnv.js +16 -15
  163. package/build/production/shared/utils/jest/E2eSsrEnv.js.map +1 -1
  164. package/build/production/shared/utils/jest/global.js +1 -1
  165. package/build/production/shared/utils/jest/global.js.map +1 -1
  166. package/build/production/shared/utils/jest/index.js +11 -11
  167. package/build/production/shared/utils/jest/index.js.map +1 -1
  168. package/build/production/shared/utils/splitComponent.js +11 -22
  169. package/build/production/shared/utils/splitComponent.js.map +1 -1
  170. package/build/production/shared/utils/time.js +3 -3
  171. package/build/production/shared/utils/time.js.map +1 -1
  172. package/build/production/shared/utils/webpack.js +6 -6
  173. package/build/production/shared/utils/webpack.js.map +1 -1
  174. package/build/types-code/client/getInj.d.ts +1 -2
  175. package/build/types-code/client/index.d.ts +1 -1
  176. package/build/types-code/index.d.ts +1 -7
  177. package/build/types-code/server/index.d.ts +6 -11
  178. package/build/types-code/server/utils/index.d.ts +1 -1
  179. package/build/types-code/shared/utils/config.d.ts +4 -2
  180. package/build/types-code/shared/utils/index.d.ts +2 -2
  181. package/build/types-code/shared/utils/splitComponent.d.ts +6 -4
  182. package/build/web/client/getInj.js +65 -0
  183. package/build/web/client/getInj.js.map +1 -0
  184. package/{src/client/index.tsx → build/web/client/index.js} +13 -24
  185. package/build/web/client/index.js.map +1 -0
  186. package/{src/client/init.ts → build/web/client/init.js} +9 -14
  187. package/build/web/client/init.js.map +1 -0
  188. package/build/web/index.js +11 -0
  189. package/build/web/index.js.map +1 -0
  190. package/{src/server/Cache.ts → build/web/server/Cache.js} +15 -22
  191. package/build/web/server/Cache.js.map +1 -0
  192. package/{src/server/index.ts → build/web/server/index.js} +32 -81
  193. package/build/web/server/index.js.map +1 -0
  194. package/{src/server/renderer.tsx → build/web/server/renderer.js} +188 -333
  195. package/build/web/server/renderer.js.map +1 -0
  196. package/{src/server/server.ts → build/web/server/server.js} +82 -182
  197. package/build/web/server/server.js.map +1 -0
  198. package/{src/server/utils/errors.ts → build/web/server/utils/errors.js} +6 -25
  199. package/build/web/server/utils/errors.js.map +1 -0
  200. package/build/web/server/utils/index.js +4 -0
  201. package/build/web/server/utils/index.js.map +1 -0
  202. package/build/web/shared/components/Button/index.js +90 -0
  203. package/build/web/shared/components/Button/index.js.map +1 -0
  204. package/build/web/shared/components/Checkbox/index.js +35 -0
  205. package/build/web/shared/components/Checkbox/index.js.map +1 -0
  206. package/{src/shared/components/GenericLink/index.tsx → build/web/shared/components/GenericLink/index.js} +44 -78
  207. package/build/web/shared/components/GenericLink/index.js.map +1 -0
  208. package/build/web/shared/components/Input/index.js +71 -0
  209. package/build/web/shared/components/Input/index.js.map +1 -0
  210. package/build/web/shared/components/Link.js +20 -0
  211. package/build/web/shared/components/Link.js.map +1 -0
  212. package/{src → build/web}/shared/components/Modal/base-theme.scss +1 -1
  213. package/build/web/shared/components/Modal/index.js +128 -0
  214. package/build/web/shared/components/Modal/index.js.map +1 -0
  215. package/build/web/shared/components/NavLink.js +13 -0
  216. package/build/web/shared/components/NavLink.js.map +1 -0
  217. package/{src → build/web}/shared/components/PageLayout/base-theme.scss +1 -1
  218. package/{src/shared/components/PageLayout/index.tsx → build/web/shared/components/PageLayout/index.js} +20 -33
  219. package/build/web/shared/components/PageLayout/index.js.map +1 -0
  220. package/build/web/shared/components/TextArea/index.js +106 -0
  221. package/build/web/shared/components/TextArea/index.js.map +1 -0
  222. package/build/web/shared/components/Throbber/index.js +26 -0
  223. package/build/web/shared/components/Throbber/index.js.map +1 -0
  224. package/{src/shared/components/WithTooltip/Tooltip.tsx → build/web/shared/components/WithTooltip/Tooltip.js} +61 -109
  225. package/build/web/shared/components/WithTooltip/Tooltip.js.map +1 -0
  226. package/build/web/shared/components/WithTooltip/index.js +117 -0
  227. package/build/web/shared/components/WithTooltip/index.js.map +1 -0
  228. package/{src/shared/components/YouTubeVideo/index.tsx → build/web/shared/components/YouTubeVideo/index.js} +23 -40
  229. package/build/web/shared/components/YouTubeVideo/index.js.map +1 -0
  230. package/build/web/shared/components/index.js +18 -0
  231. package/build/web/shared/components/index.js.map +1 -0
  232. package/build/web/shared/components/selectors/CustomDropdown/Options/index.js +82 -0
  233. package/build/web/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -0
  234. package/{src/shared/components/selectors/CustomDropdown/index.tsx → build/web/shared/components/selectors/CustomDropdown/index.js} +56 -80
  235. package/build/web/shared/components/selectors/CustomDropdown/index.js.map +1 -0
  236. package/{src/shared/components/selectors/NativeDropdown/index.tsx → build/web/shared/components/selectors/NativeDropdown/index.js} +39 -44
  237. package/build/web/shared/components/selectors/NativeDropdown/index.js.map +1 -0
  238. package/build/web/shared/components/selectors/Switch/index.js +50 -0
  239. package/build/web/shared/components/selectors/Switch/index.js.map +1 -0
  240. package/build/web/shared/components/selectors/common.js +12 -0
  241. package/build/web/shared/components/selectors/common.js.map +1 -0
  242. package/build/web/shared/components/selectors/index.js +4 -0
  243. package/build/web/shared/components/selectors/index.js.map +1 -0
  244. package/build/web/shared/utils/config.js +45 -0
  245. package/build/web/shared/utils/config.js.map +1 -0
  246. package/build/web/shared/utils/globalState.js +15 -0
  247. package/build/web/shared/utils/globalState.js.map +1 -0
  248. package/build/web/shared/utils/index.js +13 -0
  249. package/build/web/shared/utils/index.js.map +1 -0
  250. package/{src/shared/utils/isomorphy/buildInfo.ts → build/web/shared/utils/isomorphy/buildInfo.js} +4 -10
  251. package/build/web/shared/utils/isomorphy/buildInfo.js.map +1 -0
  252. package/build/web/shared/utils/isomorphy/environment-check.js +17 -0
  253. package/build/web/shared/utils/isomorphy/environment-check.js.map +1 -0
  254. package/{src/shared/utils/isomorphy/index.ts → build/web/shared/utils/isomorphy/index.js} +6 -6
  255. package/build/web/shared/utils/isomorphy/index.js.map +1 -0
  256. package/{src/shared/utils/jest/E2eSsrEnv.ts → build/web/shared/utils/jest/E2eSsrEnv.js} +73 -140
  257. package/build/web/shared/utils/jest/E2eSsrEnv.js.map +1 -0
  258. package/build/web/shared/utils/jest/global.js +4 -0
  259. package/build/web/shared/utils/jest/global.js.map +1 -0
  260. package/{src/shared/utils/jest/index.ts → build/web/shared/utils/jest/index.js} +33 -83
  261. package/build/web/shared/utils/jest/index.js.map +1 -0
  262. package/{src/shared/utils/splitComponent.tsx → build/web/shared/utils/splitComponent.js} +77 -124
  263. package/build/web/shared/utils/splitComponent.js.map +1 -0
  264. package/{src/shared/utils/time.ts → build/web/shared/utils/time.js} +21 -37
  265. package/build/web/shared/utils/time.js.map +1 -0
  266. package/build/web/shared/utils/webpack.js +67 -0
  267. package/build/web/shared/utils/webpack.js.map +1 -0
  268. package/config/babel/node-ssr.js +12 -3
  269. package/config/babel/webpack.js +6 -1
  270. package/config/jest/default.js +8 -2
  271. package/config/jest/setup.js +8 -1
  272. package/config/webpack/app-base.js +25 -14
  273. package/config/webpack/app-development.js +2 -2
  274. package/config/webpack/lib-base.js +1 -2
  275. package/package.json +41 -42
  276. package/types.d.ts +1 -6
  277. package/build/development/__chunk_groups__.json +0 -6
  278. package/build/development/style.css +0 -909
  279. package/build/development/web.bundle.js +0 -752
  280. package/build/production/__chunk_groups__.json +0 -6
  281. package/build/production/style.css +0 -2
  282. package/build/production/style.css.map +0 -1
  283. package/build/production/web.bundle.js +0 -3
  284. package/build/production/web.bundle.js.LICENSE.txt +0 -9
  285. package/build/production/web.bundle.js.map +0 -1
  286. package/dev-styles.js +0 -1
  287. package/node-entry.js +0 -15
  288. package/null.js +0 -1
  289. package/prod-styles.js +0 -1
  290. package/src/client/getInj.ts +0 -51
  291. package/src/index.ts +0 -73
  292. package/src/server/utils/index.ts +0 -3
  293. package/src/shared/components/Button/index.tsx +0 -130
  294. package/src/shared/components/Checkbox/index.tsx +0 -53
  295. package/src/shared/components/Input/index.tsx +0 -96
  296. package/src/shared/components/Link.tsx +0 -25
  297. package/src/shared/components/Modal/index.tsx +0 -177
  298. package/src/shared/components/NavLink.tsx +0 -18
  299. package/src/shared/components/TextArea/index.tsx +0 -139
  300. package/src/shared/components/Throbber/index.tsx +0 -28
  301. package/src/shared/components/WithTooltip/index.tsx +0 -186
  302. package/src/shared/components/index.ts +0 -20
  303. package/src/shared/components/selectors/CustomDropdown/Options/index.tsx +0 -124
  304. package/src/shared/components/selectors/Switch/index.tsx +0 -74
  305. package/src/shared/components/selectors/common.ts +0 -57
  306. package/src/shared/components/selectors/index.ts +0 -8
  307. package/src/shared/utils/config.ts +0 -28
  308. package/src/shared/utils/globalState.ts +0 -44
  309. package/src/shared/utils/index.ts +0 -45
  310. package/src/shared/utils/isomorphy/environment-check.ts +0 -18
  311. package/src/shared/utils/jest/global.ts +0 -17
  312. package/src/shared/utils/webpack.ts +0 -74
  313. /package/{src → build/web}/shared/components/Button/style.scss +0 -0
  314. /package/{src → build/web}/shared/components/Checkbox/theme.scss +0 -0
  315. /package/{src → build/web}/shared/components/GenericLink/style.scss +0 -0
  316. /package/{src → build/web}/shared/components/Input/theme.scss +0 -0
  317. /package/{src → build/web}/shared/components/Modal/styles.scss +0 -0
  318. /package/{src → build/web}/shared/components/TextArea/style.scss +0 -0
  319. /package/{src → build/web}/shared/components/Throbber/theme.scss +0 -0
  320. /package/{src → build/web}/shared/components/WithTooltip/default-theme.scss +0 -0
  321. /package/{src → build/web}/shared/components/YouTubeVideo/base.scss +0 -0
  322. /package/{src → build/web}/shared/components/YouTubeVideo/throbber.scss +0 -0
  323. /package/{src → build/web}/shared/components/selectors/CustomDropdown/Options/style.scss +0 -0
  324. /package/{src → build/web}/shared/components/selectors/CustomDropdown/theme.scss +0 -0
  325. /package/{src → build/web}/shared/components/selectors/NativeDropdown/theme.scss +0 -0
  326. /package/{src → build/web}/shared/components/selectors/Switch/theme.scss +0 -0
  327. /package/{src → build/web}/styles/_global/reset.css +0 -0
  328. /package/{src → build/web}/styles/_mixins/fonts.scss +0 -0
  329. /package/{src → build/web}/styles/_mixins/media.scss +0 -0
  330. /package/{src → build/web}/styles/_mixins/typography.scss +0 -0
  331. /package/{src → build/web}/styles/global.scss +0 -0
  332. /package/{src → build/web}/styles/mixins.scss +0 -0
@@ -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,38 +1,41 @@
1
- "use strict";
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");
1
+ import "core-js/modules/es.array.push.js";
2
+ import "core-js/modules/es.iterator.constructor.js";
3
+ import "core-js/modules/es.set.difference.v2.js";
4
+ import "core-js/modules/es.set.intersection.v2.js";
5
+ import "core-js/modules/es.set.is-disjoint-from.v2.js";
6
+ import "core-js/modules/es.set.is-subset-of.v2.js";
7
+ import "core-js/modules/es.set.is-superset-of.v2.js";
8
+ import "core-js/modules/es.set.symmetric-difference.v2.js";
9
+ import "core-js/modules/es.set.union.v2.js";
10
+ import "core-js/modules/es.array.push.js";
11
+ import "core-js/modules/es.iterator.constructor.js";
12
+ import "core-js/modules/es.set.difference.v2.js";
13
+ import "core-js/modules/es.set.intersection.v2.js";
14
+ import "core-js/modules/es.set.is-disjoint-from.v2.js";
15
+ import "core-js/modules/es.set.is-subset-of.v2.js";
16
+ import "core-js/modules/es.set.is-superset-of.v2.js";
17
+ import "core-js/modules/es.set.symmetric-difference.v2.js";
18
+ import "core-js/modules/es.set.union.v2.js";
14
19
  /* global document */
15
20
 
16
- // Note: At the client side we can get chunk groups immediately when loading
17
- // the module; at the server-side we only can get them within React render flow.
18
- // Thus, we set and use the following variable at the client-side, and then when
19
- // needed on the server side, we'll fetch it differently.
20
- let clientChunkGroups;
21
- if (_isomorphy.IS_CLIENT_SIDE) {
22
- // TODO: Rewrite to avoid these overrides of ESLint rules.
23
- /* eslint-disable @typescript-eslint/no-unsafe-assignment,
24
- @typescript-eslint/no-require-imports,
25
- @typescript-eslint/no-unsafe-call,
26
- @typescript-eslint/no-unsafe-member-access */
27
- clientChunkGroups = require("../../client/getInj").default().CHUNK_GROUPS ?? {};
28
- /* eslint-enable @typescript-eslint/no-unsafe-assignment,
29
- @typescript-eslint/no-require-imports,
30
- @typescript-eslint/no-unsafe-call,
31
- @typescript-eslint/no-unsafe-member-access */
21
+ import { Suspense, lazy, useInsertionEffect } from 'react';
22
+ import { Barrier } from '@dr.pogodin/js-utils';
23
+ import { getSsrContext } from "./globalState.js";
24
+ import { IS_CLIENT_SIDE, IS_SERVER_SIDE, getBuildInfo } from "./isomorphy/index.js";
25
+ import { jsx as _jsx } from "react/jsx-runtime";
26
+ function getClientChunkGroups() {
27
+ if (!IS_CLIENT_SIDE) return undefined;
28
+ return (async () => {
29
+ const {
30
+ default: getInj
31
+ } = await import(/* webpackChunkName: "react-utils-client-side-code" */"../../client/getInj");
32
+ const inj = await getInj();
33
+ return inj.CHUNK_GROUPS ?? {};
34
+ })();
32
35
  }
33
36
  const refCounts = {};
34
37
  function getPublicPath() {
35
- return (0, _isomorphy.getBuildInfo)().publicPath;
38
+ return getBuildInfo().publicPath;
36
39
  }
37
40
 
38
41
  /**
@@ -56,7 +59,7 @@ function bookStyleSheet(name, loadedSheets, refCount) {
56
59
  link.setAttribute('href', path);
57
60
  document.head.appendChild(link);
58
61
  }
59
- res = new _jsUtils.Barrier();
62
+ res = new Barrier();
60
63
  link.addEventListener('load', () => {
61
64
  if (!res) throw Error('Internal error');
62
65
  void res.resolve();
@@ -103,7 +106,7 @@ function assertChunkName(chunkName, chunkGroups) {
103
106
  * @return Resolves once all pending stylesheets, necessary for
104
107
  * the chunk, are either loaded, or failed to load.
105
108
  */
106
- async function bookStyleSheets(chunkName, chunkGroups, refCount) {
109
+ export async function bookStyleSheets(chunkName, chunkGroups, refCount) {
107
110
  const promises = [];
108
111
  const assets = chunkGroups[chunkName];
109
112
  if (!assets) return Promise.resolve();
@@ -124,7 +127,7 @@ async function bookStyleSheets(chunkName, chunkGroups, refCount) {
124
127
  * the reference counter).
125
128
  * @param {string} chunkName
126
129
  */
127
- function freeStyleSheets(chunkName, chunkGroups) {
130
+ export function freeStyleSheets(chunkName, chunkGroups) {
128
131
  const assets = chunkGroups[chunkName];
129
132
  if (!assets) return;
130
133
  for (const asset of assets) {
@@ -153,26 +156,31 @@ const usedChunkNames = new Set();
153
156
  * @param {React.Element} [options.placeholder]
154
157
  * @return {React.ElementType}
155
158
  */
156
- function splitComponent({
159
+ export default function splitComponent({
157
160
  chunkName,
158
161
  getComponent,
159
162
  placeholder
160
163
  }) {
161
- // On the client side we can check right away if the chunk name is known.
162
- if (_isomorphy.IS_CLIENT_SIDE) assertChunkName(chunkName, clientChunkGroups);
163
-
164
164
  // The correct usage of splitComponent() assumes a single call per chunk.
165
165
  if (usedChunkNames.has(chunkName)) {
166
166
  throw Error(`Repeated splitComponent() call for the chunk "${chunkName}"`);
167
167
  } else usedChunkNames.add(chunkName);
168
- const LazyComponent = /*#__PURE__*/(0, _react.lazy)(async () => {
168
+ const LazyComponent = /*#__PURE__*/lazy(async () => {
169
+ const clientChunkGroups = await getClientChunkGroups();
170
+
171
+ // On the client side we can check right away if the chunk name is known.
172
+ if (IS_CLIENT_SIDE) {
173
+ if (!clientChunkGroups) throw Error('Internal error');
174
+ assertChunkName(chunkName, clientChunkGroups);
175
+ }
169
176
  const resolved = await getComponent();
170
177
  const Component = 'default' in resolved ? resolved.default : resolved;
171
178
 
172
179
  // This pre-loads necessary stylesheets prior to the first mount of
173
180
  // the component (the lazy load function is executed by React one at
174
181
  // the frist mount).
175
- if (_isomorphy.IS_CLIENT_SIDE) {
182
+ if (IS_CLIENT_SIDE) {
183
+ if (!clientChunkGroups) throw Error('Internal error');
176
184
  await bookStyleSheets(chunkName, clientChunkGroups, false);
177
185
  }
178
186
  const Wrapper = ({
@@ -182,24 +190,25 @@ function splitComponent({
182
190
  }) => {
183
191
  // On the server side we'll assert the chunk name here,
184
192
  // and also push it to the SSR chunks array.
185
- if (_isomorphy.IS_SERVER_SIDE) {
193
+ if (IS_SERVER_SIDE) {
186
194
  const {
187
195
  chunkGroups,
188
196
  chunks
189
- } = (0, _globalState.getSsrContext)();
197
+ } = getSsrContext();
190
198
  assertChunkName(chunkName, chunkGroups);
191
199
  if (!chunks.includes(chunkName)) chunks.push(chunkName);
192
200
  }
193
201
 
194
202
  // This takes care about stylesheets management every time an instance of
195
203
  // this component is mounted / unmounted.
196
- (0, _react.useInsertionEffect)(() => {
204
+ useInsertionEffect(() => {
205
+ if (!clientChunkGroups) throw Error('Internal error');
197
206
  void bookStyleSheets(chunkName, clientChunkGroups, true);
198
207
  return () => {
199
208
  freeStyleSheets(chunkName, clientChunkGroups);
200
209
  };
201
210
  }, []);
202
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component
211
+ return /*#__PURE__*/_jsx(Component
203
212
  // eslint-disable-next-line react/jsx-props-no-spreading
204
213
  , {
205
214
  ...rest,
@@ -214,9 +223,9 @@ function splitComponent({
214
223
  const CodeSplit = ({
215
224
  children,
216
225
  ...rest
217
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Suspense, {
226
+ }) => /*#__PURE__*/_jsx(Suspense, {
218
227
  fallback: placeholder,
219
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LazyComponent
228
+ children: /*#__PURE__*/_jsx(LazyComponent
220
229
  // eslint-disable-next-line react/jsx-props-no-spreading
221
230
  , {
222
231
  ...rest,
@@ -1 +1 @@
1
- {"version":3,"file":"splitComponent.js","names":["_react","require","_jsUtils","_globalState","_isomorphy","_jsxRuntime","clientChunkGroups","IS_CLIENT_SIDE","default","CHUNK_GROUPS","refCounts","getPublicPath","getBuildInfo","publicPath","bookStyleSheet","name","loadedSheets","refCount","res","path","fullPath","document","location","origin","has","link","querySelector","createElement","setAttribute","head","appendChild","Barrier","addEventListener","Error","resolve","current","getLoadedStyleSheets","Set","styleSheets","href","add","assertChunkName","chunkName","chunkGroups","bookStyleSheets","promises","assets","Promise","asset","endsWith","promise","push","length","allSettled","then","freeStyleSheets","pathRefCount","remove","usedChunkNames","splitComponent","getComponent","placeholder","LazyComponent","lazy","resolved","Component","Wrapper","children","ref","rest","IS_SERVER_SIDE","chunks","getSsrContext","includes","useInsertionEffect","jsx","CodeSplit","Suspense","fallback"],"sources":["../../../../src/shared/utils/splitComponent.tsx"],"sourcesContent":["/* global document */\n\nimport {\n type ComponentType,\n type FunctionComponent,\n type ReactNode,\n type RefObject,\n Suspense,\n lazy,\n useInsertionEffect,\n} from 'react';\n\nimport { Barrier } from '@dr.pogodin/js-utils';\n\nimport { type ChunkGroupsT, getSsrContext } from './globalState';\n\nimport {\n IS_CLIENT_SIDE,\n IS_SERVER_SIDE,\n getBuildInfo,\n} from './isomorphy';\n\n// Note: At the client side we can get chunk groups immediately when loading\n// the module; at the server-side we only can get them within React render flow.\n// Thus, we set and use the following variable at the client-side, and then when\n// needed on the server side, we'll fetch it differently.\nlet clientChunkGroups: ChunkGroupsT;\n\nif (IS_CLIENT_SIDE) {\n // TODO: Rewrite to avoid these overrides of ESLint rules.\n /* eslint-disable @typescript-eslint/no-unsafe-assignment,\n @typescript-eslint/no-require-imports,\n @typescript-eslint/no-unsafe-call,\n @typescript-eslint/no-unsafe-member-access */\n clientChunkGroups = require('client/getInj').default().CHUNK_GROUPS ?? {};\n /* eslint-enable @typescript-eslint/no-unsafe-assignment,\n @typescript-eslint/no-require-imports,\n @typescript-eslint/no-unsafe-call,\n @typescript-eslint/no-unsafe-member-access */\n}\n\nconst refCounts: Record<string, number> = {};\n\nfunction getPublicPath() {\n return getBuildInfo().publicPath;\n}\n\n/**\n * Client-side only! Ensures the specified CSS stylesheet is loaded into\n * the document; loads if it is missing; and does simple reference counting\n * to facilitate future clean-up.\n * @param name\n * @param loadedSheets\n * @param refCount\n * @return\n */\nfunction bookStyleSheet(\n name: string,\n loadedSheets: Set<string>,\n refCount: boolean,\n): Promise<void> | undefined {\n let res: Barrier<void> | undefined;\n const path = `${getPublicPath()}/${name}`;\n const fullPath = `${document.location.origin}${path}`;\n\n if (!loadedSheets.has(fullPath)) {\n let link = document.querySelector(`link[href=\"${path}\"]`);\n\n if (!link) {\n link = document.createElement('link');\n link.setAttribute('rel', 'stylesheet');\n link.setAttribute('href', path);\n document.head.appendChild(link);\n }\n\n res = new Barrier<void>();\n link.addEventListener('load', () => {\n if (!res) throw Error('Internal error');\n void res.resolve();\n });\n link.addEventListener('error', () => {\n if (!res) throw Error('Internal error');\n void res.resolve();\n });\n }\n\n if (refCount) {\n const current = refCounts[path] ?? 0;\n refCounts[path] = 1 + current;\n }\n\n return res;\n}\n\n/**\n * Generates the set of URLs for currently loaded, linked stylesheets.\n * @return\n */\nfunction getLoadedStyleSheets(): Set<string> {\n const res = new Set<string>();\n const { styleSheets } = document;\n for (const { href } of styleSheets) {\n if (href) res.add(href);\n }\n return res;\n}\n\nfunction assertChunkName(\n chunkName: string,\n chunkGroups: ChunkGroupsT,\n) {\n if (chunkGroups[chunkName]) return;\n throw Error(`Unknown chunk name \"${chunkName}\"`);\n}\n\n/**\n * Client-side only! Ensures all CSS stylesheets required for the specified\n * code chunk are loaded into the document; loads the missing ones; and does\n * simple reference counting to facilitate future clean-up.\n * @param chunkName Chunk name.\n * @param refCount\n * @return Resolves once all pending stylesheets, necessary for\n * the chunk, are either loaded, or failed to load.\n */\nexport async function bookStyleSheets(\n chunkName: string,\n chunkGroups: ChunkGroupsT,\n refCount: boolean,\n): Promise<void> {\n const promises = [];\n const assets = chunkGroups[chunkName];\n if (!assets) return Promise.resolve();\n\n const loadedSheets = getLoadedStyleSheets();\n\n for (const asset of assets) {\n if (asset.endsWith('.css')) {\n const promise = bookStyleSheet(asset, loadedSheets, refCount);\n if (promise) promises.push(promise);\n }\n }\n\n return promises.length\n ? Promise.allSettled(promises).then()\n : Promise.resolve();\n}\n\n/**\n * Client-side only! Frees from the document all CSS stylesheets that are\n * required by the specified chunk, and have reference counter equal to one\n * (for chunks with larger reference counter values, it just decrements\n * the reference counter).\n * @param {string} chunkName\n */\nexport function freeStyleSheets(\n chunkName: string,\n chunkGroups: ChunkGroupsT,\n): void {\n const assets = chunkGroups[chunkName];\n if (!assets) return;\n\n for (const asset of assets) {\n if (asset.endsWith('.css')) {\n const path = `${getPublicPath()}/${asset}`;\n\n const pathRefCount = refCounts[path];\n if (pathRefCount) {\n if (pathRefCount <= 1) {\n document.head.querySelector(`link[href=\"${path}\"]`)!.remove();\n delete refCounts[path];\n } else refCounts[path] = pathRefCount - 1;\n }\n }\n }\n}\n\n// Holds the set of chunk names already used for splitComponent() calls.\nconst usedChunkNames = new Set();\n\ntype ComponentOrModule<PropsT> = ComponentType<PropsT> | {\n default: ComponentType<PropsT>;\n};\n\n/**\n * Given an async component retrieval function `getComponent()` it creates\n * a special \"code split\" component, which uses <Suspense> to asynchronously\n * load on demand the code required by `getComponent()`.\n * @param options\n * @param options.chunkName\n * @param {function} options.getComponent\n * @param {React.Element} [options.placeholder]\n * @return {React.ElementType}\n */\nexport default function splitComponent<\n ComponentPropsT extends { children?: ReactNode; ref?: RefObject<unknown> },\n>({\n chunkName,\n getComponent,\n placeholder,\n}: {\n chunkName: string;\n getComponent: () => Promise<ComponentOrModule<ComponentPropsT>>;\n placeholder?: ReactNode;\n}): FunctionComponent<ComponentPropsT> {\n // On the client side we can check right away if the chunk name is known.\n if (IS_CLIENT_SIDE) assertChunkName(chunkName, clientChunkGroups);\n\n // The correct usage of splitComponent() assumes a single call per chunk.\n if (usedChunkNames.has(chunkName)) {\n throw Error(`Repeated splitComponent() call for the chunk \"${chunkName}\"`);\n } else usedChunkNames.add(chunkName);\n\n const LazyComponent = lazy(async () => {\n const resolved = await getComponent();\n const Component = 'default' in resolved ? resolved.default : resolved;\n\n // This pre-loads necessary stylesheets prior to the first mount of\n // the component (the lazy load function is executed by React one at\n // the frist mount).\n if (IS_CLIENT_SIDE) {\n await bookStyleSheets(chunkName, clientChunkGroups, false);\n }\n\n const Wrapper: FunctionComponent<ComponentPropsT> = ({\n children,\n ref,\n ...rest\n }) => {\n // On the server side we'll assert the chunk name here,\n // and also push it to the SSR chunks array.\n if (IS_SERVER_SIDE) {\n const { chunkGroups, chunks } = getSsrContext()!;\n assertChunkName(chunkName, chunkGroups);\n if (!chunks.includes(chunkName)) chunks.push(chunkName);\n }\n\n // This takes care about stylesheets management every time an instance of\n // this component is mounted / unmounted.\n useInsertionEffect(() => {\n void bookStyleSheets(chunkName, clientChunkGroups, true);\n return () => {\n freeStyleSheets(chunkName, clientChunkGroups);\n };\n }, []);\n\n return (\n <Component\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...(rest as unknown as ComponentPropsT)}\n ref={ref}\n >\n {children}\n </Component>\n );\n };\n\n return { default: Wrapper };\n });\n\n const CodeSplit: React.FunctionComponent<ComponentPropsT> = ({\n children,\n ...rest\n }: ComponentPropsT) => (\n <Suspense fallback={placeholder}>\n <LazyComponent\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...rest as Parameters<typeof LazyComponent>[0]}\n >\n {children}\n </LazyComponent>\n </Suspense>\n );\n\n return CodeSplit;\n}\n"],"mappings":";;;;;;;;AAEA,IAAAA,MAAA,GAAAC,OAAA;AAUA,IAAAC,QAAA,GAAAD,OAAA;AAEA,IAAAE,YAAA,GAAAF,OAAA;AAEA,IAAAG,UAAA,GAAAH,OAAA;AAIqB,IAAAI,WAAA,GAAAJ,OAAA;AApBrB;;AAsBA;AACA;AACA;AACA;AACA,IAAIK,iBAA+B;AAEnC,IAAIC,yBAAc,EAAE;EAClB;EACA;AACF;AACA;AACA;EACED,iBAAiB,GAAGL,OAAO,sBAAgB,CAAC,CAACO,OAAO,CAAC,CAAC,CAACC,YAAY,IAAI,CAAC,CAAC;EACzE;AACF;AACA;AACA;AACA;AAEA,MAAMC,SAAiC,GAAG,CAAC,CAAC;AAE5C,SAASC,aAAaA,CAAA,EAAG;EACvB,OAAO,IAAAC,uBAAY,EAAC,CAAC,CAACC,UAAU;AAClC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,cAAcA,CACrBC,IAAY,EACZC,YAAyB,EACzBC,QAAiB,EACU;EAC3B,IAAIC,GAA8B;EAClC,MAAMC,IAAI,GAAG,GAAGR,aAAa,CAAC,CAAC,IAAII,IAAI,EAAE;EACzC,MAAMK,QAAQ,GAAG,GAAGC,QAAQ,CAACC,QAAQ,CAACC,MAAM,GAAGJ,IAAI,EAAE;EAErD,IAAI,CAACH,YAAY,CAACQ,GAAG,CAACJ,QAAQ,CAAC,EAAE;IAC/B,IAAIK,IAAI,GAAGJ,QAAQ,CAACK,aAAa,CAAC,cAAcP,IAAI,IAAI,CAAC;IAEzD,IAAI,CAACM,IAAI,EAAE;MACTA,IAAI,GAAGJ,QAAQ,CAACM,aAAa,CAAC,MAAM,CAAC;MACrCF,IAAI,CAACG,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC;MACtCH,IAAI,CAACG,YAAY,CAAC,MAAM,EAAET,IAAI,CAAC;MAC/BE,QAAQ,CAACQ,IAAI,CAACC,WAAW,CAACL,IAAI,CAAC;IACjC;IAEAP,GAAG,GAAG,IAAIa,gBAAO,CAAO,CAAC;IACzBN,IAAI,CAACO,gBAAgB,CAAC,MAAM,EAAE,MAAM;MAClC,IAAI,CAACd,GAAG,EAAE,MAAMe,KAAK,CAAC,gBAAgB,CAAC;MACvC,KAAKf,GAAG,CAACgB,OAAO,CAAC,CAAC;IACpB,CAAC,CAAC;IACFT,IAAI,CAACO,gBAAgB,CAAC,OAAO,EAAE,MAAM;MACnC,IAAI,CAACd,GAAG,EAAE,MAAMe,KAAK,CAAC,gBAAgB,CAAC;MACvC,KAAKf,GAAG,CAACgB,OAAO,CAAC,CAAC;IACpB,CAAC,CAAC;EACJ;EAEA,IAAIjB,QAAQ,EAAE;IACZ,MAAMkB,OAAO,GAAGzB,SAAS,CAACS,IAAI,CAAC,IAAI,CAAC;IACpCT,SAAS,CAACS,IAAI,CAAC,GAAG,CAAC,GAAGgB,OAAO;EAC/B;EAEA,OAAOjB,GAAG;AACZ;;AAEA;AACA;AACA;AACA;AACA,SAASkB,oBAAoBA,CAAA,EAAgB;EAC3C,MAAMlB,GAAG,GAAG,IAAImB,GAAG,CAAS,CAAC;EAC7B,MAAM;IAAEC;EAAY,CAAC,GAAGjB,QAAQ;EAChC,KAAK,MAAM;IAAEkB;EAAK,CAAC,IAAID,WAAW,EAAE;IAClC,IAAIC,IAAI,EAAErB,GAAG,CAACsB,GAAG,CAACD,IAAI,CAAC;EACzB;EACA,OAAOrB,GAAG;AACZ;AAEA,SAASuB,eAAeA,CACtBC,SAAiB,EACjBC,WAAyB,EACzB;EACA,IAAIA,WAAW,CAACD,SAAS,CAAC,EAAE;EAC5B,MAAMT,KAAK,CAAC,uBAAuBS,SAAS,GAAG,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeE,eAAeA,CACnCF,SAAiB,EACjBC,WAAyB,EACzB1B,QAAiB,EACF;EACf,MAAM4B,QAAQ,GAAG,EAAE;EACnB,MAAMC,MAAM,GAAGH,WAAW,CAACD,SAAS,CAAC;EACrC,IAAI,CAACI,MAAM,EAAE,OAAOC,OAAO,CAACb,OAAO,CAAC,CAAC;EAErC,MAAMlB,YAAY,GAAGoB,oBAAoB,CAAC,CAAC;EAE3C,KAAK,MAAMY,KAAK,IAAIF,MAAM,EAAE;IAC1B,IAAIE,KAAK,CAACC,QAAQ,CAAC,MAAM,CAAC,EAAE;MAC1B,MAAMC,OAAO,GAAGpC,cAAc,CAACkC,KAAK,EAAEhC,YAAY,EAAEC,QAAQ,CAAC;MAC7D,IAAIiC,OAAO,EAAEL,QAAQ,CAACM,IAAI,CAACD,OAAO,CAAC;IACrC;EACF;EAEA,OAAOL,QAAQ,CAACO,MAAM,GAClBL,OAAO,CAACM,UAAU,CAACR,QAAQ,CAAC,CAACS,IAAI,CAAC,CAAC,GACnCP,OAAO,CAACb,OAAO,CAAC,CAAC;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASqB,eAAeA,CAC7Bb,SAAiB,EACjBC,WAAyB,EACnB;EACN,MAAMG,MAAM,GAAGH,WAAW,CAACD,SAAS,CAAC;EACrC,IAAI,CAACI,MAAM,EAAE;EAEb,KAAK,MAAME,KAAK,IAAIF,MAAM,EAAE;IAC1B,IAAIE,KAAK,CAACC,QAAQ,CAAC,MAAM,CAAC,EAAE;MAC1B,MAAM9B,IAAI,GAAG,GAAGR,aAAa,CAAC,CAAC,IAAIqC,KAAK,EAAE;MAE1C,MAAMQ,YAAY,GAAG9C,SAAS,CAACS,IAAI,CAAC;MACpC,IAAIqC,YAAY,EAAE;QAChB,IAAIA,YAAY,IAAI,CAAC,EAAE;UACrBnC,QAAQ,CAACQ,IAAI,CAACH,aAAa,CAAC,cAAcP,IAAI,IAAI,CAAC,CAAEsC,MAAM,CAAC,CAAC;UAC7D,OAAO/C,SAAS,CAACS,IAAI,CAAC;QACxB,CAAC,MAAMT,SAAS,CAACS,IAAI,CAAC,GAAGqC,YAAY,GAAG,CAAC;MAC3C;IACF;EACF;AACF;;AAEA;AACA,MAAME,cAAc,GAAG,IAAIrB,GAAG,CAAC,CAAC;AAMhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASsB,cAAcA,CAEpC;EACAjB,SAAS;EACTkB,YAAY;EACZC;AAKF,CAAC,EAAsC;EACrC;EACA,IAAItD,yBAAc,EAAEkC,eAAe,CAACC,SAAS,EAAEpC,iBAAiB,CAAC;;EAEjE;EACA,IAAIoD,cAAc,CAAClC,GAAG,CAACkB,SAAS,CAAC,EAAE;IACjC,MAAMT,KAAK,CAAC,iDAAiDS,SAAS,GAAG,CAAC;EAC5E,CAAC,MAAMgB,cAAc,CAAClB,GAAG,CAACE,SAAS,CAAC;EAEpC,MAAMoB,aAAa,gBAAG,IAAAC,WAAI,EAAC,YAAY;IACrC,MAAMC,QAAQ,GAAG,MAAMJ,YAAY,CAAC,CAAC;IACrC,MAAMK,SAAS,GAAG,SAAS,IAAID,QAAQ,GAAGA,QAAQ,CAACxD,OAAO,GAAGwD,QAAQ;;IAErE;IACA;IACA;IACA,IAAIzD,yBAAc,EAAE;MAClB,MAAMqC,eAAe,CAACF,SAAS,EAAEpC,iBAAiB,EAAE,KAAK,CAAC;IAC5D;IAEA,MAAM4D,OAA2C,GAAGA,CAAC;MACnDC,QAAQ;MACRC,GAAG;MACH,GAAGC;IACL,CAAC,KAAK;MACJ;MACA;MACA,IAAIC,yBAAc,EAAE;QAClB,MAAM;UAAE3B,WAAW;UAAE4B;QAAO,CAAC,GAAG,IAAAC,0BAAa,EAAC,CAAE;QAChD/B,eAAe,CAACC,SAAS,EAAEC,WAAW,CAAC;QACvC,IAAI,CAAC4B,MAAM,CAACE,QAAQ,CAAC/B,SAAS,CAAC,EAAE6B,MAAM,CAACpB,IAAI,CAACT,SAAS,CAAC;MACzD;;MAEA;MACA;MACA,IAAAgC,yBAAkB,EAAC,MAAM;QACvB,KAAK9B,eAAe,CAACF,SAAS,EAAEpC,iBAAiB,EAAE,IAAI,CAAC;QACxD,OAAO,MAAM;UACXiD,eAAe,CAACb,SAAS,EAAEpC,iBAAiB,CAAC;QAC/C,CAAC;MACH,CAAC,EAAE,EAAE,CAAC;MAEN,oBACE,IAAAD,WAAA,CAAAsE,GAAA,EAACV;MACC;MAAA;QAAA,GACKI,IAAI;QACTD,GAAG,EAAEA,GAAI;QAAAD,QAAA,EAERA;MAAQ,CACA,CAAC;IAEhB,CAAC;IAED,OAAO;MAAE3D,OAAO,EAAE0D;IAAQ,CAAC;EAC7B,CAAC,CAAC;EAEF,MAAMU,SAAmD,GAAGA,CAAC;IAC3DT,QAAQ;IACR,GAAGE;EACY,CAAC,kBAChB,IAAAhE,WAAA,CAAAsE,GAAA,EAAC3E,MAAA,CAAA6E,QAAQ;IAACC,QAAQ,EAAEjB,WAAY;IAAAM,QAAA,eAC9B,IAAA9D,WAAA,CAAAsE,GAAA,EAACb;IACC;IAAA;MAAA,GACIO,IAAI;MAAAF,QAAA,EAEPA;IAAQ,CACI;EAAC,CACR,CACX;EAED,OAAOS,SAAS;AAClB","ignoreList":[]}
1
+ {"version":3,"file":"splitComponent.js","names":["Suspense","lazy","useInsertionEffect","Barrier","getSsrContext","IS_CLIENT_SIDE","IS_SERVER_SIDE","getBuildInfo","jsx","_jsx","getClientChunkGroups","undefined","default","getInj","inj","CHUNK_GROUPS","refCounts","getPublicPath","publicPath","bookStyleSheet","name","loadedSheets","refCount","res","path","fullPath","document","location","origin","has","link","querySelector","createElement","setAttribute","head","appendChild","addEventListener","Error","resolve","current","getLoadedStyleSheets","Set","styleSheets","href","add","assertChunkName","chunkName","chunkGroups","bookStyleSheets","promises","assets","Promise","asset","endsWith","promise","push","length","allSettled","then","freeStyleSheets","pathRefCount","remove","usedChunkNames","splitComponent","getComponent","placeholder","LazyComponent","clientChunkGroups","resolved","Component","Wrapper","children","ref","rest","chunks","includes","CodeSplit","fallback"],"sources":["../../../../src/shared/utils/splitComponent.tsx"],"sourcesContent":["/* global document */\n\nimport {\n type ComponentType,\n type FunctionComponent,\n type ReactNode,\n type RefObject,\n Suspense,\n lazy,\n useInsertionEffect,\n} from 'react';\n\nimport { Barrier } from '@dr.pogodin/js-utils';\n\nimport { type ChunkGroupsT, getSsrContext } from './globalState';\n\nimport {\n IS_CLIENT_SIDE,\n IS_SERVER_SIDE,\n getBuildInfo,\n} from './isomorphy';\n\nfunction getClientChunkGroups(): Promise<ChunkGroupsT> | undefined {\n if (!IS_CLIENT_SIDE) return undefined;\n\n return (async () => {\n const { default: getInj } = await import(/* webpackChunkName: \"react-utils-client-side-code\" */ '../../client/getInj');\n\n const inj = await getInj();\n return inj.CHUNK_GROUPS ?? {};\n })();\n}\n\nconst refCounts: Record<string, number> = {};\n\nfunction getPublicPath() {\n return getBuildInfo().publicPath;\n}\n\n/**\n * Client-side only! Ensures the specified CSS stylesheet is loaded into\n * the document; loads if it is missing; and does simple reference counting\n * to facilitate future clean-up.\n * @param name\n * @param loadedSheets\n * @param refCount\n * @return\n */\nfunction bookStyleSheet(\n name: string,\n loadedSheets: Set<string>,\n refCount: boolean,\n): Promise<void> | undefined {\n let res: Barrier<void> | undefined;\n const path = `${getPublicPath()}/${name}`;\n const fullPath = `${document.location.origin}${path}`;\n\n if (!loadedSheets.has(fullPath)) {\n let link = document.querySelector(`link[href=\"${path}\"]`);\n\n if (!link) {\n link = document.createElement('link');\n link.setAttribute('rel', 'stylesheet');\n link.setAttribute('href', path);\n document.head.appendChild(link);\n }\n\n res = new Barrier<void>();\n link.addEventListener('load', () => {\n if (!res) throw Error('Internal error');\n void res.resolve();\n });\n link.addEventListener('error', () => {\n if (!res) throw Error('Internal error');\n void res.resolve();\n });\n }\n\n if (refCount) {\n const current = refCounts[path] ?? 0;\n refCounts[path] = 1 + current;\n }\n\n return res;\n}\n\n/**\n * Generates the set of URLs for currently loaded, linked stylesheets.\n * @return\n */\nfunction getLoadedStyleSheets(): Set<string> {\n const res = new Set<string>();\n const { styleSheets } = document;\n for (const { href } of styleSheets) {\n if (href) res.add(href);\n }\n return res;\n}\n\nfunction assertChunkName(\n chunkName: string,\n chunkGroups: ChunkGroupsT,\n) {\n if (chunkGroups[chunkName]) return;\n throw Error(`Unknown chunk name \"${chunkName}\"`);\n}\n\n/**\n * Client-side only! Ensures all CSS stylesheets required for the specified\n * code chunk are loaded into the document; loads the missing ones; and does\n * simple reference counting to facilitate future clean-up.\n * @param chunkName Chunk name.\n * @param refCount\n * @return Resolves once all pending stylesheets, necessary for\n * the chunk, are either loaded, or failed to load.\n */\nexport async function bookStyleSheets(\n chunkName: string,\n chunkGroups: ChunkGroupsT,\n refCount: boolean,\n): Promise<void> {\n const promises = [];\n const assets = chunkGroups[chunkName];\n if (!assets) return Promise.resolve();\n\n const loadedSheets = getLoadedStyleSheets();\n\n for (const asset of assets) {\n if (asset.endsWith('.css')) {\n const promise = bookStyleSheet(asset, loadedSheets, refCount);\n if (promise) promises.push(promise);\n }\n }\n\n return promises.length\n ? Promise.allSettled(promises).then()\n : Promise.resolve();\n}\n\n/**\n * Client-side only! Frees from the document all CSS stylesheets that are\n * required by the specified chunk, and have reference counter equal to one\n * (for chunks with larger reference counter values, it just decrements\n * the reference counter).\n * @param {string} chunkName\n */\nexport function freeStyleSheets(\n chunkName: string,\n chunkGroups: ChunkGroupsT,\n): void {\n const assets = chunkGroups[chunkName];\n if (!assets) return;\n\n for (const asset of assets) {\n if (asset.endsWith('.css')) {\n const path = `${getPublicPath()}/${asset}`;\n\n const pathRefCount = refCounts[path];\n if (pathRefCount) {\n if (pathRefCount <= 1) {\n document.head.querySelector(`link[href=\"${path}\"]`)!.remove();\n delete refCounts[path];\n } else refCounts[path] = pathRefCount - 1;\n }\n }\n }\n}\n\n// Holds the set of chunk names already used for splitComponent() calls.\nconst usedChunkNames = new Set();\n\ntype ComponentOrModule<PropsT> = ComponentType<PropsT> | {\n default: ComponentType<PropsT>;\n};\n\ntype GenericComponentPropsT = {\n children?: ReactNode;\n ref?: RefObject<unknown>;\n\n // NOTE: This is necessary, as without it this type (with only optional\n // fields) will be conisdered as \"weak\" by TypeScript, and it will be\n // a error to assign to it any type that does not use \"children\", or \"ref\".\n [propName: string]: unknown;\n};\n\n/**\n * Given an async component retrieval function `getComponent()` it creates\n * a special \"code split\" component, which uses <Suspense> to asynchronously\n * load on demand the code required by `getComponent()`.\n * @param options\n * @param options.chunkName\n * @param {function} options.getComponent\n * @param {React.Element} [options.placeholder]\n * @return {React.ElementType}\n */\nexport default function splitComponent<\n ComponentPropsT extends GenericComponentPropsT,\n>({\n chunkName,\n getComponent,\n placeholder,\n}: {\n chunkName: string;\n getComponent: () => Promise<ComponentOrModule<ComponentPropsT>>;\n placeholder?: ReactNode;\n}): FunctionComponent<ComponentPropsT> {\n // The correct usage of splitComponent() assumes a single call per chunk.\n if (usedChunkNames.has(chunkName)) {\n throw Error(`Repeated splitComponent() call for the chunk \"${chunkName}\"`);\n } else usedChunkNames.add(chunkName);\n\n const LazyComponent = lazy(async () => {\n const clientChunkGroups = await getClientChunkGroups();\n\n // On the client side we can check right away if the chunk name is known.\n if (IS_CLIENT_SIDE) {\n if (!clientChunkGroups) throw Error('Internal error');\n assertChunkName(chunkName, clientChunkGroups);\n }\n\n const resolved = await getComponent();\n const Component = 'default' in resolved ? resolved.default : resolved;\n\n // This pre-loads necessary stylesheets prior to the first mount of\n // the component (the lazy load function is executed by React one at\n // the frist mount).\n if (IS_CLIENT_SIDE) {\n if (!clientChunkGroups) throw Error('Internal error');\n await bookStyleSheets(chunkName, clientChunkGroups, false);\n }\n\n const Wrapper: FunctionComponent<ComponentPropsT> = ({\n children,\n ref,\n ...rest\n }) => {\n // On the server side we'll assert the chunk name here,\n // and also push it to the SSR chunks array.\n if (IS_SERVER_SIDE) {\n const { chunkGroups, chunks } = getSsrContext()!;\n assertChunkName(chunkName, chunkGroups);\n if (!chunks.includes(chunkName)) chunks.push(chunkName);\n }\n\n // This takes care about stylesheets management every time an instance of\n // this component is mounted / unmounted.\n useInsertionEffect(() => {\n if (!clientChunkGroups) throw Error('Internal error');\n void bookStyleSheets(chunkName, clientChunkGroups, true);\n return () => {\n freeStyleSheets(chunkName, clientChunkGroups);\n };\n }, []);\n\n return (\n <Component\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...(rest as unknown as ComponentPropsT)}\n ref={ref}\n >\n {children}\n </Component>\n );\n };\n\n return { default: Wrapper };\n });\n\n const CodeSplit: React.FunctionComponent<ComponentPropsT> = ({\n children,\n ...rest\n }: ComponentPropsT) => (\n <Suspense fallback={placeholder}>\n <LazyComponent\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...rest as Parameters<typeof LazyComponent>[0]}\n >\n {children}\n </LazyComponent>\n </Suspense>\n );\n\n return CodeSplit;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,18 +1,9 @@
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
- exports.useCurrent = useCurrent;
9
- exports.useTimezoneOffset = useTimezoneOffset;
10
- var _cookie = require("cookie");
11
- var _react = require("react");
12
- var _dayjs = _interopRequireDefault(require("dayjs"));
13
- var _jsUtils = require("@dr.pogodin/js-utils");
14
- var _reactGlobalState = require("@dr.pogodin/react-global-state");
15
- var _globalState = require("./globalState");
1
+ import { serialize } from 'cookie';
2
+ import { useEffect } from 'react';
3
+ import dayjs from 'dayjs';
4
+ import { DAY_MS, HOUR_MS, MIN_MS, SEC_MS, YEAR_MS, timer } from '@dr.pogodin/js-utils';
5
+ import { useGlobalState } from '@dr.pogodin/react-global-state';
6
+ import { getSsrContext } from "./globalState.js";
16
7
  /**
17
8
  * This react hook wraps Date.now() function in a SSR friendly way,
18
9
  * ensuring that all calls to useCurrent() within the same render return
@@ -23,13 +14,13 @@ var _globalState = require("./globalState");
23
14
  */
24
15
  // TODO: Should we request the state type as generic parameter, to be able
25
16
  // to verify the give globalStatePath is correct?
26
- function useCurrent({
17
+ export function useCurrent({
27
18
  autorefresh = false,
28
19
  globalStatePath = 'currentTime',
29
- precision = 5 * _jsUtils.SEC_MS
20
+ precision = 5 * SEC_MS
30
21
  } = {}) {
31
- const [now, setter] = (0, _reactGlobalState.useGlobalState)(globalStatePath, Date.now);
32
- (0, _react.useEffect)(() => {
22
+ const [now, setter] = useGlobalState(globalStatePath, Date.now);
23
+ useEffect(() => {
33
24
  let timerId;
34
25
  const update = () => {
35
26
  setter(old => {
@@ -57,21 +48,21 @@ function useCurrent({
57
48
  */
58
49
  // TODO: Should we request the state type as generic parameter, to be able
59
50
  // to verify the give globalStatePath is correct?
60
- function useTimezoneOffset({
51
+ export function useTimezoneOffset({
61
52
  cookieName = 'timezoneOffset',
62
53
  globalStatePath = 'timezoneOffset'
63
54
  } = {}) {
64
- const ssrContext = (0, _globalState.getSsrContext)(false);
65
- const [offset, setOffset] = (0, _reactGlobalState.useGlobalState)(globalStatePath, () => {
55
+ const ssrContext = getSsrContext(false);
56
+ const [offset, setOffset] = useGlobalState(globalStatePath, () => {
66
57
  const value = cookieName && ssrContext?.req.cookies[cookieName];
67
58
  return value ? parseInt(value) : 0;
68
59
  });
69
- (0, _react.useEffect)(() => {
60
+ useEffect(() => {
70
61
  const date = new Date();
71
62
  const value = date.getTimezoneOffset();
72
63
  setOffset(value);
73
64
  if (cookieName) {
74
- document.cookie = (0, _cookie.serialize)(cookieName, value.toString(), {
65
+ document.cookie = serialize(cookieName, value.toString(), {
75
66
  path: '/'
76
67
  });
77
68
  }
@@ -79,15 +70,15 @@ function useTimezoneOffset({
79
70
  return offset;
80
71
  }
81
72
  const time = {
82
- DAY_MS: _jsUtils.DAY_MS,
83
- HOUR_MS: _jsUtils.HOUR_MS,
84
- MIN_MS: _jsUtils.MIN_MS,
85
- SEC_MS: _jsUtils.SEC_MS,
86
- YEAR_MS: _jsUtils.YEAR_MS,
73
+ DAY_MS,
74
+ HOUR_MS,
75
+ MIN_MS,
76
+ SEC_MS,
77
+ YEAR_MS,
87
78
  now: Date.now,
88
- timer: _jsUtils.timer,
79
+ timer,
89
80
  useCurrent,
90
81
  useTimezoneOffset
91
82
  };
92
- var _default = exports.default = Object.assign(_dayjs.default, time);
83
+ export default Object.assign(dayjs, time);
93
84
  //# sourceMappingURL=time.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","names":["_cookie","require","_react","_dayjs","_interopRequireDefault","_jsUtils","_reactGlobalState","_globalState","useCurrent","autorefresh","globalStatePath","precision","SEC_MS","now","setter","useGlobalState","Date","useEffect","timerId","update","old","neu","Math","abs","setTimeout","clearTimeout","useTimezoneOffset","cookieName","ssrContext","getSsrContext","offset","setOffset","value","req","cookies","parseInt","date","getTimezoneOffset","document","cookie","serialize","toString","path","time","DAY_MS","HOUR_MS","MIN_MS","YEAR_MS","timer","_default","exports","default","Object","assign","dayjs"],"sources":["../../../../src/shared/utils/time.ts"],"sourcesContent":["import { serialize } from 'cookie';\nimport { useEffect } from 'react';\nimport dayjs from 'dayjs';\n\nimport {\n DAY_MS,\n HOUR_MS,\n MIN_MS,\n SEC_MS,\n YEAR_MS,\n timer,\n} from '@dr.pogodin/js-utils';\n\nimport { type ForceT, useGlobalState } from '@dr.pogodin/react-global-state';\n\nimport { getSsrContext } from './globalState';\n\n/**\n * This react hook wraps Date.now() function in a SSR friendly way,\n * ensuring that all calls to useCurrent() within the same render return\n * exactly the same time (which is retrieved from Date.now() first, and\n * then stored in the global state to be reused in all other calls), which\n * is also passed and used in the first client side render, and then updated\n * with a finite precision to avoid infinite re-rendering loops.\n */\n// TODO: Should we request the state type as generic parameter, to be able\n// to verify the give globalStatePath is correct?\nexport function useCurrent({\n autorefresh = false,\n globalStatePath = 'currentTime',\n precision = 5 * SEC_MS,\n} = {}): number {\n const [now, setter] = useGlobalState<ForceT, number>(\n globalStatePath,\n Date.now,\n );\n useEffect(() => {\n let timerId: NodeJS.Timeout | undefined;\n const update = (): void => {\n setter((old) => {\n const neu = Date.now();\n return Math.abs(neu - old) > precision ? neu : old;\n });\n if (autorefresh) timerId = setTimeout(update, precision);\n };\n update();\n return (): void => {\n if (timerId) clearTimeout(timerId);\n };\n }, [autorefresh, precision, setter]);\n return now;\n}\n\n/**\n * Wraps the standard Date.getTimezoneOffset() method in a SSR-friendly way.\n * This hook retrieves the offset value at the client side and uses a cookie\n * to pass it to the server in subsequent requests from that user. At the server\n * side the value from cookie is used in renders and passed back to the client\n * via the global state. Prior to the value being known (in the very first\n * request from the user, when the cookie is still missing), zero value is used\n * as the default value.\n */\n// TODO: Should we request the state type as generic parameter, to be able\n// to verify the give globalStatePath is correct?\nexport function useTimezoneOffset({\n cookieName = 'timezoneOffset',\n globalStatePath = 'timezoneOffset',\n} = {}): number {\n const ssrContext = getSsrContext(false);\n const [offset, setOffset] = useGlobalState<ForceT, number>(\n globalStatePath,\n () => {\n const value = cookieName\n && ssrContext?.req.cookies[cookieName] as string;\n return value ? parseInt(value) : 0;\n },\n );\n useEffect(() => {\n const date = new Date();\n const value = date.getTimezoneOffset();\n setOffset(value);\n if (cookieName) {\n document.cookie = serialize(cookieName, value.toString(), { path: '/' });\n }\n }, [cookieName, setOffset]);\n return offset;\n}\n\nconst time = {\n DAY_MS,\n HOUR_MS,\n MIN_MS,\n SEC_MS,\n YEAR_MS,\n now: Date.now,\n timer,\n useCurrent,\n useTimezoneOffset,\n};\n\nexport default Object.assign(dayjs, time);\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"time.js","names":["serialize","useEffect","dayjs","DAY_MS","HOUR_MS","MIN_MS","SEC_MS","YEAR_MS","timer","useGlobalState","getSsrContext","useCurrent","autorefresh","globalStatePath","precision","now","setter","Date","timerId","update","old","neu","Math","abs","setTimeout","clearTimeout","useTimezoneOffset","cookieName","ssrContext","offset","setOffset","value","req","cookies","parseInt","date","getTimezoneOffset","document","cookie","toString","path","time","Object","assign"],"sources":["../../../../src/shared/utils/time.ts"],"sourcesContent":["import { serialize } from 'cookie';\nimport { useEffect } from 'react';\nimport dayjs from 'dayjs';\n\nimport {\n DAY_MS,\n HOUR_MS,\n MIN_MS,\n SEC_MS,\n YEAR_MS,\n timer,\n} from '@dr.pogodin/js-utils';\n\nimport { type ForceT, useGlobalState } from '@dr.pogodin/react-global-state';\n\nimport { getSsrContext } from './globalState';\n\n/**\n * This react hook wraps Date.now() function in a SSR friendly way,\n * ensuring that all calls to useCurrent() within the same render return\n * exactly the same time (which is retrieved from Date.now() first, and\n * then stored in the global state to be reused in all other calls), which\n * is also passed and used in the first client side render, and then updated\n * with a finite precision to avoid infinite re-rendering loops.\n */\n// TODO: Should we request the state type as generic parameter, to be able\n// to verify the give globalStatePath is correct?\nexport function useCurrent({\n autorefresh = false,\n globalStatePath = 'currentTime',\n precision = 5 * SEC_MS,\n} = {}): number {\n const [now, setter] = useGlobalState<ForceT, number>(\n globalStatePath,\n Date.now,\n );\n useEffect(() => {\n let timerId: NodeJS.Timeout | undefined;\n const update = (): void => {\n setter((old) => {\n const neu = Date.now();\n return Math.abs(neu - old) > precision ? neu : old;\n });\n if (autorefresh) timerId = setTimeout(update, precision);\n };\n update();\n return (): void => {\n if (timerId) clearTimeout(timerId);\n };\n }, [autorefresh, precision, setter]);\n return now;\n}\n\n/**\n * Wraps the standard Date.getTimezoneOffset() method in a SSR-friendly way.\n * This hook retrieves the offset value at the client side and uses a cookie\n * to pass it to the server in subsequent requests from that user. At the server\n * side the value from cookie is used in renders and passed back to the client\n * via the global state. Prior to the value being known (in the very first\n * request from the user, when the cookie is still missing), zero value is used\n * as the default value.\n */\n// TODO: Should we request the state type as generic parameter, to be able\n// to verify the give globalStatePath is correct?\nexport function useTimezoneOffset({\n cookieName = 'timezoneOffset',\n globalStatePath = 'timezoneOffset',\n} = {}): number {\n const ssrContext = getSsrContext(false);\n const [offset, setOffset] = useGlobalState<ForceT, number>(\n globalStatePath,\n () => {\n const value = cookieName\n && ssrContext?.req.cookies[cookieName] as string;\n return value ? parseInt(value) : 0;\n },\n );\n useEffect(() => {\n const date = new Date();\n const value = date.getTimezoneOffset();\n setOffset(value);\n if (cookieName) {\n document.cookie = serialize(cookieName, value.toString(), { path: '/' });\n }\n }, [cookieName, setOffset]);\n return offset;\n}\n\nconst time = {\n DAY_MS,\n HOUR_MS,\n MIN_MS,\n SEC_MS,\n YEAR_MS,\n now: Date.now,\n timer,\n useCurrent,\n useTimezoneOffset,\n};\n\nexport default Object.assign(dayjs, time);\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,QAAQ;AAClC,SAASC,SAAS,QAAQ,OAAO;AACjC,OAAOC,KAAK,MAAM,OAAO;AAEzB,SACEC,MAAM,EACNC,OAAO,EACPC,MAAM,EACNC,MAAM,EACNC,OAAO,EACPC,KAAK,QACA,sBAAsB;AAE7B,SAAsBC,cAAc,QAAQ,gCAAgC;AAAA,SAEnEC,aAAa;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAAC;EACzBC,WAAW,GAAG,KAAK;EACnBC,eAAe,GAAG,aAAa;EAC/BC,SAAS,GAAG,CAAC,GAAGR;AAClB,CAAC,GAAG,CAAC,CAAC,EAAU;EACd,MAAM,CAACS,GAAG,EAAEC,MAAM,CAAC,GAAGP,cAAc,CAClCI,eAAe,EACfI,IAAI,CAACF,GACP,CAAC;EACDd,SAAS,CAAC,MAAM;IACd,IAAIiB,OAAmC;IACvC,MAAMC,MAAM,GAAGA,CAAA,KAAY;MACzBH,MAAM,CAAEI,GAAG,IAAK;QACd,MAAMC,GAAG,GAAGJ,IAAI,CAACF,GAAG,CAAC,CAAC;QACtB,OAAOO,IAAI,CAACC,GAAG,CAACF,GAAG,GAAGD,GAAG,CAAC,GAAGN,SAAS,GAAGO,GAAG,GAAGD,GAAG;MACpD,CAAC,CAAC;MACF,IAAIR,WAAW,EAAEM,OAAO,GAAGM,UAAU,CAACL,MAAM,EAAEL,SAAS,CAAC;IAC1D,CAAC;IACDK,MAAM,CAAC,CAAC;IACR,OAAO,MAAY;MACjB,IAAID,OAAO,EAAEO,YAAY,CAACP,OAAO,CAAC;IACpC,CAAC;EACH,CAAC,EAAE,CAACN,WAAW,EAAEE,SAAS,EAAEE,MAAM,CAAC,CAAC;EACpC,OAAOD,GAAG;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASW,iBAAiBA,CAAC;EAChCC,UAAU,GAAG,gBAAgB;EAC7Bd,eAAe,GAAG;AACpB,CAAC,GAAG,CAAC,CAAC,EAAU;EACd,MAAMe,UAAU,GAAGlB,aAAa,CAAC,KAAK,CAAC;EACvC,MAAM,CAACmB,MAAM,EAAEC,SAAS,CAAC,GAAGrB,cAAc,CACxCI,eAAe,EACf,MAAM;IACJ,MAAMkB,KAAK,GAAGJ,UAAU,IACnBC,UAAU,EAAEI,GAAG,CAACC,OAAO,CAACN,UAAU,CAAW;IAClD,OAAOI,KAAK,GAAGG,QAAQ,CAACH,KAAK,CAAC,GAAG,CAAC;EACpC,CACF,CAAC;EACD9B,SAAS,CAAC,MAAM;IACd,MAAMkC,IAAI,GAAG,IAAIlB,IAAI,CAAC,CAAC;IACvB,MAAMc,KAAK,GAAGI,IAAI,CAACC,iBAAiB,CAAC,CAAC;IACtCN,SAAS,CAACC,KAAK,CAAC;IAChB,IAAIJ,UAAU,EAAE;MACdU,QAAQ,CAACC,MAAM,GAAGtC,SAAS,CAAC2B,UAAU,EAAEI,KAAK,CAACQ,QAAQ,CAAC,CAAC,EAAE;QAAEC,IAAI,EAAE;MAAI,CAAC,CAAC;IAC1E;EACF,CAAC,EAAE,CAACb,UAAU,EAAEG,SAAS,CAAC,CAAC;EAC3B,OAAOD,MAAM;AACf;AAEA,MAAMY,IAAI,GAAG;EACXtC,MAAM;EACNC,OAAO;EACPC,MAAM;EACNC,MAAM;EACNC,OAAO;EACPQ,GAAG,EAAEE,IAAI,CAACF,GAAG;EACbP,KAAK;EACLG,UAAU;EACVe;AACF,CAAC;AAED,eAAegB,MAAM,CAACC,MAAM,CAACzC,KAAK,EAAEuC,IAAI,CAAC","ignoreList":[]}