@qwickapps/react-framework 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +1688 -2
  2. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  3. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  4. package/dist/components/ErrorBoundary.d.ts +7 -0
  5. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  6. package/dist/components/Html.d.ts +28 -18
  7. package/dist/components/Html.d.ts.map +1 -1
  8. package/dist/components/Logo.d.ts +12 -35
  9. package/dist/components/Logo.d.ts.map +1 -1
  10. package/dist/components/Markdown.d.ts +18 -13
  11. package/dist/components/Markdown.d.ts.map +1 -1
  12. package/dist/components/QwickApp.d.ts +16 -3
  13. package/dist/components/QwickApp.d.ts.map +1 -1
  14. package/dist/components/QwickIcon.d.ts +23 -0
  15. package/dist/components/QwickIcon.d.ts.map +1 -0
  16. package/dist/components/SafeSpan.d.ts +12 -5
  17. package/dist/components/SafeSpan.d.ts.map +1 -1
  18. package/dist/components/Scaffold.d.ts.map +1 -1
  19. package/dist/components/base/ModelView.d.ts +101 -0
  20. package/dist/components/base/ModelView.d.ts.map +1 -0
  21. package/dist/components/base/index.d.ts +11 -0
  22. package/dist/components/base/index.d.ts.map +1 -0
  23. package/dist/components/blocks/Article.d.ts +12 -2
  24. package/dist/components/blocks/Article.d.ts.map +1 -1
  25. package/dist/components/blocks/Code.d.ts +13 -2
  26. package/dist/components/blocks/Code.d.ts.map +1 -1
  27. package/dist/components/blocks/Content.d.ts.map +1 -1
  28. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  30. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  31. package/dist/components/blocks/Footer.d.ts.map +1 -1
  32. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  33. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  34. package/dist/components/blocks/Image.d.ts +41 -0
  35. package/dist/components/blocks/Image.d.ts.map +1 -0
  36. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  37. package/dist/components/blocks/ProductCard.d.ts.map +1 -1
  38. package/dist/components/blocks/Section.d.ts +16 -2
  39. package/dist/components/blocks/Section.d.ts.map +1 -1
  40. package/dist/components/blocks/Text.d.ts +41 -0
  41. package/dist/components/blocks/Text.d.ts.map +1 -0
  42. package/dist/components/blocks/index.d.ts +4 -0
  43. package/dist/components/blocks/index.d.ts.map +1 -1
  44. package/dist/components/buttons/Button.d.ts +23 -7
  45. package/dist/components/buttons/Button.d.ts.map +1 -1
  46. package/dist/components/forms/FormBlock.d.ts +19 -13
  47. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  48. package/dist/components/index.d.ts +4 -0
  49. package/dist/components/index.d.ts.map +1 -1
  50. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  51. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  52. package/dist/components/input/HtmlInputField.d.ts +17 -11
  53. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  54. package/dist/components/input/SelectInputField.d.ts +16 -10
  55. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  56. package/dist/components/input/SwitchInputField.d.ts +16 -10
  57. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  58. package/dist/components/input/TextField.d.ts.map +1 -1
  59. package/dist/components/input/TextInputField.d.ts +16 -11
  60. package/dist/components/input/TextInputField.d.ts.map +1 -1
  61. package/dist/components/layout/GridCell.d.ts +23 -6
  62. package/dist/components/layout/GridCell.d.ts.map +1 -1
  63. package/dist/components/layout/GridLayout.d.ts +24 -23
  64. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  65. package/dist/components/pages/FormPage.d.ts.map +1 -1
  66. package/dist/components/pages/Page.d.ts +49 -87
  67. package/dist/components/pages/Page.d.ts.map +1 -1
  68. package/dist/components/pages/index.d.ts +2 -2
  69. package/dist/components/pages/index.d.ts.map +1 -1
  70. package/dist/config/AppConfig.d.ts +49 -0
  71. package/dist/config/AppConfig.d.ts.map +1 -0
  72. package/dist/config/AppConfigBuilder.d.ts +75 -0
  73. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  74. package/dist/config/index.d.ts +13 -0
  75. package/dist/config/index.d.ts.map +1 -0
  76. package/dist/config/types.d.ts +130 -0
  77. package/dist/config/types.d.ts.map +1 -0
  78. package/dist/config.d.ts +15 -0
  79. package/dist/config.d.ts.map +1 -0
  80. package/dist/config.esm.js +451 -0
  81. package/dist/config.js +455 -0
  82. package/dist/contexts/PrintModeContext.d.ts +27 -0
  83. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  84. package/dist/contexts/QwickAppContext.d.ts +2 -2
  85. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  86. package/dist/contexts/ThemeContext.d.ts.map +1 -1
  87. package/dist/contexts/index.d.ts +2 -0
  88. package/dist/contexts/index.d.ts.map +1 -1
  89. package/dist/hooks/index.d.ts +2 -0
  90. package/dist/hooks/index.d.ts.map +1 -1
  91. package/dist/hooks/usePrintMode.d.ts +39 -0
  92. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  93. package/dist/index.css +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.esm.css +1 -1
  97. package/dist/index.esm.js +20722 -16021
  98. package/dist/index.js +20725 -16010
  99. package/dist/schemas/CodeSchema.d.ts +2 -1
  100. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  101. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  102. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  103. package/dist/schemas/ContentSchema.d.ts +2 -1
  104. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  105. package/dist/schemas/GridCellSchema.d.ts +25 -0
  106. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  107. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  108. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  109. package/dist/schemas/HtmlSchema.d.ts +14 -0
  110. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  111. package/dist/schemas/ImageSchema.d.ts +32 -0
  112. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  113. package/dist/schemas/LogoSchema.d.ts +35 -0
  114. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  115. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  116. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  117. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  118. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  119. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  120. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  121. package/dist/schemas/SectionSchema.d.ts +2 -1
  122. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  123. package/dist/schemas/TextSchema.d.ts +37 -0
  124. package/dist/schemas/TextSchema.d.ts.map +1 -0
  125. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  126. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  127. package/dist/schemas/index.d.ts +15 -1
  128. package/dist/schemas/index.d.ts.map +1 -1
  129. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  130. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  131. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  132. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  133. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  134. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  135. package/dist/schemas/transformers/registry.d.ts +15 -0
  136. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  137. package/dist/schemas/types/Serializable.d.ts +46 -0
  138. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  139. package/dist/utils/htmlTransform.d.ts.map +1 -1
  140. package/dist/utils/reactUtils.d.ts +12 -3
  141. package/dist/utils/reactUtils.d.ts.map +1 -1
  142. package/package.json +17 -3
  143. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  145. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  148. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  150. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  152. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  154. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  155. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  156. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  158. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  159. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  160. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  161. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  162. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  163. package/src/__tests__/components/Logo.test.js +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  165. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  166. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  167. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  168. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  169. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  172. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  173. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  174. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  175. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  176. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  177. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  178. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  179. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  180. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  181. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  182. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  183. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  184. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  185. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  186. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  187. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  188. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  189. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  190. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  191. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  192. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  193. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  194. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  195. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  196. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  197. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  198. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  199. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  200. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  201. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  202. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  203. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  204. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  205. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  206. package/src/components/ErrorBoundary.tsx +8 -8
  207. package/src/components/Html.tsx +147 -44
  208. package/src/components/Logo.tsx +198 -100
  209. package/src/components/Markdown.tsx +125 -16
  210. package/src/components/QwickApp.tsx +64 -31
  211. package/src/components/QwickIcon.tsx +59 -0
  212. package/src/components/SafeSpan.tsx +65 -10
  213. package/src/components/Scaffold.tsx +2 -8
  214. package/src/components/base/ModelView.tsx +199 -0
  215. package/src/components/base/index.ts +11 -0
  216. package/src/components/blocks/Article.tsx +57 -18
  217. package/src/components/blocks/Code.md +529 -0
  218. package/src/components/blocks/Code.tsx +102 -15
  219. package/src/components/blocks/Content.tsx +25 -77
  220. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  221. package/src/components/blocks/FeatureCard.tsx +1 -2
  222. package/src/components/blocks/FeatureGrid.tsx +19 -1
  223. package/src/components/blocks/Footer.tsx +13 -1
  224. package/src/components/blocks/HeroBlock.tsx +87 -20
  225. package/src/components/blocks/Image.tsx +395 -0
  226. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  227. package/src/components/blocks/ProductCard.tsx +51 -52
  228. package/src/components/blocks/Section.tsx +113 -8
  229. package/src/components/blocks/Text.tsx +285 -0
  230. package/src/components/blocks/index.ts +4 -0
  231. package/src/components/buttons/Button.tsx +184 -15
  232. package/src/components/forms/FormBlock.tsx +70 -17
  233. package/src/components/index.ts +5 -0
  234. package/src/components/input/ChoiceInputField.tsx +48 -18
  235. package/src/components/input/HtmlInputField.tsx +48 -18
  236. package/src/components/input/SelectInputField.tsx +48 -16
  237. package/src/components/input/SwitchInputField.tsx +48 -17
  238. package/src/components/input/TextField.tsx +41 -1
  239. package/src/components/input/TextInputField.tsx +52 -18
  240. package/src/components/layout/GridCell.tsx +118 -9
  241. package/src/components/layout/GridLayout.tsx +125 -24
  242. package/src/components/pages/FormPage.tsx +0 -1
  243. package/src/components/pages/Page.css +304 -332
  244. package/src/components/pages/Page.tsx +307 -255
  245. package/src/components/pages/index.ts +2 -2
  246. package/src/config/AppConfig.ts +133 -0
  247. package/src/config/AppConfigBuilder.ts +421 -0
  248. package/src/config/__tests__/AppConfig.test.ts +385 -0
  249. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  250. package/src/config/index.ts +24 -0
  251. package/src/config/types.ts +170 -0
  252. package/src/config.ts +25 -0
  253. package/src/contexts/PrintModeContext.tsx +332 -0
  254. package/src/contexts/QwickAppContext.tsx +2 -2
  255. package/src/contexts/ThemeContext.tsx +1 -2
  256. package/src/contexts/index.ts +2 -0
  257. package/src/hooks/index.ts +5 -1
  258. package/src/hooks/usePrintMode.ts +73 -0
  259. package/src/index.ts +3 -0
  260. package/src/schemas/CodeSchema.ts +3 -3
  261. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  262. package/src/schemas/ContentSchema.ts +2 -1
  263. package/src/schemas/GridCellSchema.ts +164 -0
  264. package/src/schemas/GridLayoutSchema.ts +133 -0
  265. package/src/schemas/HtmlSchema.ts +47 -0
  266. package/src/schemas/ImageSchema.ts +235 -0
  267. package/src/schemas/LogoSchema.ts +241 -0
  268. package/src/schemas/MarkdownSchema.ts +47 -0
  269. package/src/schemas/PageTemplateSchema.ts +186 -0
  270. package/src/schemas/PrintConfigSchema.ts +207 -0
  271. package/src/schemas/README.md +661 -0
  272. package/src/schemas/SectionSchema.ts +2 -1
  273. package/src/schemas/TextSchema.ts +329 -0
  274. package/src/schemas/ViewModelSchema.ts +115 -0
  275. package/src/schemas/index.ts +21 -2
  276. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  277. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  278. package/src/schemas/transformers/registry.ts +72 -0
  279. package/src/schemas/types/Serializable.ts +51 -0
  280. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  281. package/src/stories/Article.stories.tsx +433 -433
  282. package/src/stories/Button.stories.tsx +1 -1
  283. package/src/stories/CardListGrid.stories.tsx +451 -451
  284. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  285. package/src/stories/Code.stories.tsx +1 -1
  286. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  287. package/src/stories/Content.stories.tsx +393 -393
  288. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  289. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  290. package/src/stories/DataProvider.stories.tsx +1192 -1192
  291. package/src/stories/FeatureCard.stories.tsx +557 -557
  292. package/src/stories/FeatureGrid.stories.tsx +594 -594
  293. package/src/stories/Footer.stories.tsx +640 -640
  294. package/src/stories/FormBlock.stories.tsx +760 -760
  295. package/src/stories/FormComponents.stories.tsx +349 -541
  296. package/src/stories/GridCell.stories.tsx +417 -0
  297. package/src/stories/GridLayout.stories.tsx +353 -0
  298. package/src/stories/HeroBlock.stories.tsx +862 -373
  299. package/src/stories/HtmlInputField.stories.tsx +474 -474
  300. package/src/stories/Image.stories.tsx +819 -0
  301. package/src/stories/Introduction.stories.tsx +667 -667
  302. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  303. package/src/stories/Logo.stories.tsx +165 -6
  304. package/src/stories/Markdown.stories.tsx +137 -137
  305. package/src/stories/ModelView.stories.tsx +477 -0
  306. package/src/stories/Page.stories.tsx +688 -688
  307. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  308. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  309. package/src/stories/ProductCard.stories.tsx +424 -424
  310. package/src/stories/QwickApp.stories.tsx +368 -368
  311. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  312. package/src/stories/SafeSpan.stories.tsx +531 -531
  313. package/src/stories/Section.stories.tsx +90 -2
  314. package/src/stories/SelectInputField.stories.tsx +524 -524
  315. package/src/stories/Text.stories.tsx +560 -0
  316. package/src/stories/TextInputField.stories.tsx +443 -443
  317. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  318. package/src/utils/htmlTransform.tsx +74 -53
  319. package/src/utils/reactUtils.tsx +57 -6
  320. package/dist/index.bundled.css +0 -12
  321. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  322. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  323. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  324. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  325. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -0,0 +1,442 @@
1
+ /**
2
+ * Text Component Performance Tests
3
+ *
4
+ * Performance benchmarks and optimization tests for the Text component
5
+ * to ensure it meets the established performance targets (<1ms serialization).
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import React from 'react';
11
+ import { render } from '@testing-library/react';
12
+ import '@testing-library/jest-dom';
13
+ import { ComponentTransformer } from '../../../schemas/transformers/ComponentTransformer';
14
+ import { Text } from '../../../components/blocks/Text';
15
+
16
+ describe('Text Performance', () => {
17
+ beforeEach(() => {
18
+ // Clear component registry for clean tests
19
+ ComponentTransformer.clearRegistry();
20
+
21
+ // Register Text component
22
+ ComponentTransformer.registerComponent(Text as any);
23
+ });
24
+
25
+ afterEach(() => {
26
+ ComponentTransformer.clearRegistry();
27
+ });
28
+
29
+ describe('Serialization Performance', () => {
30
+ it('should serialize simple text in under 1ms', () => {
31
+ const component = <Text content="Simple performance test" variant="body1" />;
32
+
33
+ const iterations = 100;
34
+ const times: number[] = [];
35
+
36
+ // Warm up
37
+ for (let i = 0; i < 10; i++) {
38
+ ComponentTransformer.serialize(component);
39
+ }
40
+
41
+ // Measure
42
+ for (let i = 0; i < iterations; i++) {
43
+ const startTime = performance.now();
44
+ ComponentTransformer.serialize(component);
45
+ const endTime = performance.now();
46
+ times.push(endTime - startTime);
47
+ }
48
+
49
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
50
+ const maxTime = Math.max(...times);
51
+
52
+ expect(averageTime).toBeLessThan(1); // Average under 1ms
53
+ expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
54
+ });
55
+
56
+ it('should serialize complex text with all properties in under 1ms', () => {
57
+ const component = (
58
+ <Text
59
+ content="Complex performance test with many properties"
60
+ variant="h2"
61
+ color="primary"
62
+ align="center"
63
+ component="h1"
64
+ fontWeight="bold"
65
+ textDecoration="underline"
66
+ textTransform="uppercase"
67
+ noWrap={true}
68
+ paragraph={false}
69
+ gutterBottom={true}
70
+ fontSize="2.5rem"
71
+ lineHeight="1.2"
72
+ letterSpacing="0.1em"
73
+ fontFamily="Arial, sans-serif"
74
+ customColor="#1976d2"
75
+ maxWidth="600px"
76
+ />
77
+ );
78
+
79
+ const iterations = 100;
80
+ const times: number[] = [];
81
+
82
+ // Warm up
83
+ for (let i = 0; i < 10; i++) {
84
+ ComponentTransformer.serialize(component);
85
+ }
86
+
87
+ // Measure
88
+ for (let i = 0; i < iterations; i++) {
89
+ const startTime = performance.now();
90
+ ComponentTransformer.serialize(component);
91
+ const endTime = performance.now();
92
+ times.push(endTime - startTime);
93
+ }
94
+
95
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
96
+ const maxTime = Math.max(...times);
97
+
98
+ expect(averageTime).toBeLessThan(1); // Average under 1ms
99
+ expect(maxTime).toBeLessThan(20); // Even worst case under 20ms (test environment can have spikes)
100
+ });
101
+
102
+ it('should serialize large text content efficiently', () => {
103
+ const largeContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '.repeat(200); // ~11KB
104
+ const component = (
105
+ <Text
106
+ content={largeContent}
107
+ variant="body1"
108
+ paragraph={true}
109
+ maxWidth="800px"
110
+ />
111
+ );
112
+
113
+ const iterations = 50;
114
+ const times: number[] = [];
115
+
116
+ // Warm up
117
+ for (let i = 0; i < 5; i++) {
118
+ ComponentTransformer.serialize(component);
119
+ }
120
+
121
+ // Measure
122
+ for (let i = 0; i < iterations; i++) {
123
+ const startTime = performance.now();
124
+ ComponentTransformer.serialize(component);
125
+ const endTime = performance.now();
126
+ times.push(endTime - startTime);
127
+ }
128
+
129
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
130
+ const maxTime = Math.max(...times);
131
+
132
+ expect(averageTime).toBeLessThan(2); // Large content under 2ms average
133
+ expect(maxTime).toBeLessThan(5); // Even worst case under 5ms
134
+ });
135
+ });
136
+
137
+ describe('Deserialization Performance', () => {
138
+ it('should deserialize simple text in under 1ms', () => {
139
+ const component = <Text content="Simple deserialization test" variant="body1" />;
140
+ const serialized = ComponentTransformer.serialize(component);
141
+
142
+ const iterations = 100;
143
+ const times: number[] = [];
144
+
145
+ // Warm up
146
+ for (let i = 0; i < 10; i++) {
147
+ ComponentTransformer.deserialize(serialized);
148
+ }
149
+
150
+ // Measure
151
+ for (let i = 0; i < iterations; i++) {
152
+ const startTime = performance.now();
153
+ ComponentTransformer.deserialize(serialized);
154
+ const endTime = performance.now();
155
+ times.push(endTime - startTime);
156
+ }
157
+
158
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
159
+ const maxTime = Math.max(...times);
160
+
161
+ expect(averageTime).toBeLessThan(1); // Average under 1ms
162
+ expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
163
+ });
164
+
165
+ it('should deserialize complex text in under 1ms', () => {
166
+ const component = (
167
+ <Text
168
+ content="Complex deserialization test"
169
+ variant="h3"
170
+ color="secondary"
171
+ align="right"
172
+ fontWeight="600"
173
+ textDecoration="overline"
174
+ textTransform="capitalize"
175
+ gutterBottom={true}
176
+ fontSize="1.8rem"
177
+ customColor="#ff5722"
178
+ />
179
+ );
180
+ const serialized = ComponentTransformer.serialize(component);
181
+
182
+ const iterations = 100;
183
+ const times: number[] = [];
184
+
185
+ // Warm up
186
+ for (let i = 0; i < 10; i++) {
187
+ ComponentTransformer.deserialize(serialized);
188
+ }
189
+
190
+ // Measure
191
+ for (let i = 0; i < iterations; i++) {
192
+ const startTime = performance.now();
193
+ ComponentTransformer.deserialize(serialized);
194
+ const endTime = performance.now();
195
+ times.push(endTime - startTime);
196
+ }
197
+
198
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
199
+ const maxTime = Math.max(...times);
200
+
201
+ expect(averageTime).toBeLessThan(1); // Average under 1ms
202
+ expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
203
+ });
204
+ });
205
+
206
+ describe('Round-trip Performance', () => {
207
+ it.skip('should complete serialize → deserialize → render cycle efficiently', () => {
208
+ const component = (
209
+ <Text
210
+ content="Round-trip performance test"
211
+ variant="h4"
212
+ color="info"
213
+ fontWeight="bold"
214
+ gutterBottom={true}
215
+ />
216
+ );
217
+
218
+ const iterations = 50;
219
+ const times: number[] = [];
220
+
221
+ // Warm up
222
+ for (let i = 0; i < 5; i++) {
223
+ const serialized = ComponentTransformer.serialize(component);
224
+ const deserialized = ComponentTransformer.deserialize(serialized);
225
+ render(deserialized as React.ReactElement);
226
+ }
227
+
228
+ // Measure complete round-trip
229
+ for (let i = 0; i < iterations; i++) {
230
+ const startTime = performance.now();
231
+
232
+ const serialized = ComponentTransformer.serialize(component);
233
+ const deserialized = ComponentTransformer.deserialize(serialized);
234
+ const { container } = render(deserialized as React.ReactElement);
235
+
236
+ // Ensure DOM is actually updated
237
+ container.querySelector('.MuiTypography-root');
238
+
239
+ const endTime = performance.now();
240
+ times.push(endTime - startTime);
241
+ }
242
+
243
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
244
+ const maxTime = Math.max(...times);
245
+
246
+ expect(averageTime).toBeLessThan(5); // Complete round-trip under 5ms average
247
+ expect(maxTime).toBeLessThan(20); // Even worst case under 20ms (DOM rendering can be slow in tests)
248
+ });
249
+ });
250
+
251
+ describe('Memory Performance', () => {
252
+ it('should not create memory leaks during serialization', () => {
253
+ const component = <Text content="Memory leak test" variant="body1" />;
254
+
255
+ // Get initial memory usage (if available)
256
+ const initialMemory = (performance as any).memory?.usedJSHeapSize || 0;
257
+
258
+ // Perform many serialization operations
259
+ for (let i = 0; i < 1000; i++) {
260
+ ComponentTransformer.serialize(component);
261
+ }
262
+
263
+ // Force garbage collection if available
264
+ if ((global as any).gc) {
265
+ (global as any).gc();
266
+ }
267
+
268
+ // Check memory hasn't grown significantly
269
+ const finalMemory = (performance as any).memory?.usedJSHeapSize || 0;
270
+
271
+ if (initialMemory > 0) {
272
+ const memoryGrowth = finalMemory - initialMemory;
273
+ const memoryGrowthMB = memoryGrowth / (1024 * 1024);
274
+
275
+ // Should not grow by more than 1MB for 1000 serializations
276
+ expect(memoryGrowthMB).toBeLessThan(1);
277
+ }
278
+ });
279
+
280
+ it('should handle large batch operations efficiently', () => {
281
+ const components = Array.from({ length: 100 }, (_, i) => (
282
+ <Text
283
+ content={`Batch test item ${i}`}
284
+ variant={i % 2 === 0 ? 'h3' : 'body1'}
285
+ color={i % 3 === 0 ? 'primary' : 'textSecondary'}
286
+ />
287
+ ));
288
+
289
+ const startTime = performance.now();
290
+
291
+ // Serialize all components
292
+ const serialized = components.map(component => ComponentTransformer.serialize(component));
293
+
294
+ // Deserialize all components
295
+ const deserialized = serialized.map(data => ComponentTransformer.deserialize(data));
296
+
297
+ const endTime = performance.now();
298
+ const totalTime = endTime - startTime;
299
+
300
+ expect(serialized).toHaveLength(100);
301
+ expect(deserialized).toHaveLength(100);
302
+ expect(totalTime).toBeLessThan(100); // 100 components in under 100ms (1ms per component)
303
+ });
304
+ });
305
+
306
+ describe('Rendering Performance', () => {
307
+ it.skip('should render efficiently with default props', () => {
308
+ const component = <Text content="Render performance test" />;
309
+
310
+ const iterations = 100;
311
+ const times: number[] = [];
312
+
313
+ // Warm up React rendering
314
+ for (let i = 0; i < 10; i++) {
315
+ render(component);
316
+ }
317
+
318
+ // Measure rendering time
319
+ for (let i = 0; i < iterations; i++) {
320
+ const startTime = performance.now();
321
+ render(component);
322
+ const endTime = performance.now();
323
+ times.push(endTime - startTime);
324
+ }
325
+
326
+ const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
327
+ const maxTime = Math.max(...times);
328
+
329
+ expect(averageTime).toBeLessThan(3); // Average render under 3ms
330
+ expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
331
+ });
332
+
333
+ it('should render large text content efficiently', () => {
334
+ const largeContent = 'Lorem ipsum dolor sit amet. '.repeat(500); // ~14KB
335
+ const component = <Text content={largeContent} variant="body1" />;
336
+
337
+ const startTime = performance.now();
338
+ render(component);
339
+ const endTime = performance.now();
340
+
341
+ expect(endTime - startTime).toBeLessThan(10); // Large content render under 10ms
342
+ });
343
+
344
+ it('should handle rapid prop changes efficiently', () => {
345
+ const { rerender } = render(<Text content="Initial" variant="body1" />);
346
+
347
+ const startTime = performance.now();
348
+
349
+ // Simulate rapid prop changes
350
+ for (let i = 0; i < 50; i++) {
351
+ rerender(
352
+ <Text
353
+ content={`Update ${i}`}
354
+ variant={i % 2 === 0 ? 'h4' : 'body2'}
355
+ color={i % 3 === 0 ? 'primary' : 'textSecondary'}
356
+ />
357
+ );
358
+ }
359
+
360
+ const endTime = performance.now();
361
+ const totalTime = endTime - startTime;
362
+
363
+ expect(totalTime).toBeLessThan(100); // 50 re-renders under 100ms (2ms per update)
364
+ });
365
+ });
366
+
367
+ describe('Performance Targets Validation', () => {
368
+ it('should meet all performance targets consistently', () => {
369
+ const simpleComponent = <Text content="Performance target test" />;
370
+ const complexComponent = (
371
+ <Text
372
+ content="Complex performance target test"
373
+ variant="h2"
374
+ color="primary"
375
+ align="center"
376
+ fontWeight="bold"
377
+ fontSize="2rem"
378
+ customColor="#1976d2"
379
+ gutterBottom={true}
380
+ />
381
+ );
382
+
383
+ // Test multiple iterations for consistency
384
+ const results = {
385
+ simpleSerialize: [] as number[],
386
+ simpleDeserialize: [] as number[],
387
+ complexSerialize: [] as number[],
388
+ complexDeserialize: [] as number[]
389
+ };
390
+
391
+ // Warm up
392
+ for (let i = 0; i < 10; i++) {
393
+ ComponentTransformer.serialize(simpleComponent);
394
+ ComponentTransformer.serialize(complexComponent);
395
+ }
396
+
397
+ // Measure
398
+ for (let i = 0; i < 100; i++) {
399
+ // Simple serialize
400
+ let start = performance.now();
401
+ ComponentTransformer.serialize(simpleComponent);
402
+ results.simpleSerialize.push(performance.now() - start);
403
+
404
+ // Simple deserialize
405
+ const simpleSerialized = ComponentTransformer.serialize(simpleComponent);
406
+ start = performance.now();
407
+ ComponentTransformer.deserialize(simpleSerialized);
408
+ results.simpleDeserialize.push(performance.now() - start);
409
+
410
+ // Complex serialize
411
+ start = performance.now();
412
+ ComponentTransformer.serialize(complexComponent);
413
+ results.complexSerialize.push(performance.now() - start);
414
+
415
+ // Complex deserialize
416
+ const complexSerialized = ComponentTransformer.serialize(complexComponent);
417
+ start = performance.now();
418
+ ComponentTransformer.deserialize(complexSerialized);
419
+ results.complexDeserialize.push(performance.now() - start);
420
+ }
421
+
422
+ // Calculate statistics
423
+ const stats = Object.entries(results).map(([key, times]) => ({
424
+ operation: key,
425
+ average: times.reduce((sum, time) => sum + time, 0) / times.length,
426
+ max: Math.max(...times),
427
+ min: Math.min(...times),
428
+ p95: times.sort((a, b) => a - b)[Math.floor(times.length * 0.95)]
429
+ }));
430
+
431
+ // Validate targets
432
+ stats.forEach(stat => {
433
+ console.log(`${stat.operation}: avg=${stat.average.toFixed(3)}ms, max=${stat.max.toFixed(3)}ms, p95=${stat.p95.toFixed(3)}ms`);
434
+
435
+ // Main targets: average under 1ms, p95 under 2ms
436
+ expect(stat.average).toBeLessThan(1);
437
+ expect(stat.p95).toBeLessThan(2);
438
+ expect(stat.max).toBeLessThan(5); // Conservative upper bound
439
+ });
440
+ });
441
+ });
442
+ });