meno-core 1.0.53 → 1.1.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 (415) hide show
  1. package/.claude/settings.local.json +1 -3
  2. package/bin/cli.ts +66 -261
  3. package/build-astro.ts +150 -128
  4. package/dist/bin/cli.js +42 -185
  5. package/dist/bin/cli.js.map +2 -2
  6. package/dist/chunks/chunk-2AR55GYH.js +42 -0
  7. package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
  8. package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
  9. package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
  10. package/dist/chunks/chunk-4ZRU52J2.js +169 -0
  11. package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
  12. package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
  13. package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
  14. package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
  15. package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
  16. package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
  17. package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
  18. package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
  19. package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
  20. package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
  21. package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
  22. package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
  23. package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
  24. package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
  25. package/dist/lib/client/index.js +1003 -475
  26. package/dist/lib/client/index.js.map +3 -3
  27. package/dist/lib/server/index.js +14393 -6371
  28. package/dist/lib/server/index.js.map +4 -4
  29. package/dist/lib/shared/index.js +342 -101
  30. package/dist/lib/shared/index.js.map +4 -4
  31. package/dist/lib/shared/richtext/index.js +1 -1
  32. package/dist/lib/test-utils/index.js +64 -80
  33. package/dist/lib/test-utils/index.js.map +2 -2
  34. package/entries/client-router.tsx +10 -8
  35. package/lib/client/ClientInitializer.ts +8 -8
  36. package/lib/client/ErrorBoundary.test.tsx +246 -186
  37. package/lib/client/ErrorBoundary.tsx +183 -132
  38. package/lib/client/componentRegistry.test.ts +96 -108
  39. package/lib/client/componentRegistry.ts +1 -3
  40. package/lib/client/contexts/ThemeContext.tsx +3 -2
  41. package/lib/client/core/ComponentBuilder.test.ts +663 -560
  42. package/lib/client/core/ComponentBuilder.ts +427 -155
  43. package/lib/client/core/ComponentRenderer.test.tsx +2 -4
  44. package/lib/client/core/ComponentRenderer.tsx +46 -33
  45. package/lib/client/core/builders/embedBuilder.ts +242 -54
  46. package/lib/client/core/builders/linkBuilder.ts +72 -45
  47. package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
  48. package/lib/client/core/builders/listBuilder.ts +155 -89
  49. package/lib/client/core/builders/localeListBuilder.ts +97 -62
  50. package/lib/client/core/builders/types.ts +5 -5
  51. package/lib/client/core/cmsTemplateProcessor.ts +8 -9
  52. package/lib/client/elementRegistry.ts +3 -3
  53. package/lib/client/fontFamiliesService.test.ts +2 -10
  54. package/lib/client/fontFamiliesService.ts +3 -3
  55. package/lib/client/hmr/HMRManager.tsx +47 -30
  56. package/lib/client/hmrCssReload.ts +49 -14
  57. package/lib/client/hmrWebSocket.ts +14 -19
  58. package/lib/client/hooks/useColorVariables.test.ts +21 -21
  59. package/lib/client/hooks/useColorVariables.ts +23 -18
  60. package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
  61. package/lib/client/hooks/useVariables.ts +6 -4
  62. package/lib/client/hydration/HydrationUtils.test.ts +24 -25
  63. package/lib/client/hydration/HydrationUtils.ts +3 -4
  64. package/lib/client/i18nConfigService.test.ts +2 -7
  65. package/lib/client/i18nConfigService.ts +2 -2
  66. package/lib/client/meno-filter/MenoFilter.test.ts +47 -49
  67. package/lib/client/meno-filter/MenoFilter.ts +14 -15
  68. package/lib/client/meno-filter/bindings.ts +18 -43
  69. package/lib/client/meno-filter/init.ts +4 -4
  70. package/lib/client/meno-filter/renderer.ts +30 -32
  71. package/lib/client/meno-filter/script.generated.ts +1 -3
  72. package/lib/client/meno-filter/ui.ts +4 -6
  73. package/lib/client/meno-filter/updates.ts +18 -23
  74. package/lib/client/meno-filter/utils.ts +1 -1
  75. package/lib/client/navigation.test.ts +174 -178
  76. package/lib/client/navigation.ts +0 -1
  77. package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
  78. package/lib/client/responsiveStyleResolver.test.ts +234 -232
  79. package/lib/client/responsiveStyleResolver.ts +74 -20
  80. package/lib/client/routing/RouteLoader.test.ts +24 -25
  81. package/lib/client/routing/RouteLoader.ts +27 -35
  82. package/lib/client/routing/Router.tsx +210 -153
  83. package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
  84. package/lib/client/scripts/ScriptExecutor.ts +18 -36
  85. package/lib/client/services/PrefetchService.test.ts +3 -3
  86. package/lib/client/services/PrefetchService.ts +23 -29
  87. package/lib/client/styleProcessor.test.ts +9 -9
  88. package/lib/client/styleProcessor.ts +24 -15
  89. package/lib/client/styles/StyleInjector.test.ts +122 -115
  90. package/lib/client/styles/StyleInjector.ts +10 -7
  91. package/lib/client/styles/UtilityClassCollector.ts +62 -28
  92. package/lib/client/styles/cspNonce.test.ts +2 -5
  93. package/lib/client/templateEngine.test.ts +554 -488
  94. package/lib/client/templateEngine.ts +203 -73
  95. package/lib/client/theme.test.ts +1 -1
  96. package/lib/client/theme.ts +0 -1
  97. package/lib/client/utils/toast.ts +0 -1
  98. package/lib/server/__integration__/api-routes.test.ts +8 -4
  99. package/lib/server/__integration__/cms-integration.test.ts +1 -4
  100. package/lib/server/__integration__/server-lifecycle.test.ts +4 -5
  101. package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
  102. package/lib/server/__integration__/static-assets.test.ts +3 -3
  103. package/lib/server/__integration__/test-helpers.ts +87 -74
  104. package/lib/server/ab/generateFunctions.ts +12 -10
  105. package/lib/server/astro/cmsPageEmitter.ts +26 -42
  106. package/lib/server/astro/componentEmitter.ts +35 -43
  107. package/lib/server/astro/cssCollector.ts +10 -26
  108. package/lib/server/astro/nodeToAstro.test.ts +1754 -34
  109. package/lib/server/astro/nodeToAstro.ts +232 -216
  110. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
  111. package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
  112. package/lib/server/astro/pageEmitter.ts +9 -13
  113. package/lib/server/astro/tailwindMapper.test.ts +10 -37
  114. package/lib/server/astro/tailwindMapper.ts +33 -40
  115. package/lib/server/astro/templateTransformer.ts +17 -20
  116. package/lib/server/createServer.ts +7 -19
  117. package/lib/server/cssGenerator.test.ts +35 -44
  118. package/lib/server/cssGenerator.ts +8 -19
  119. package/lib/server/fileWatcher.test.ts +164 -13
  120. package/lib/server/fileWatcher.ts +209 -124
  121. package/lib/server/index.ts +14 -17
  122. package/lib/server/jsonLoader.test.ts +39 -2
  123. package/lib/server/jsonLoader.ts +39 -34
  124. package/lib/server/middleware/cors.test.ts +21 -21
  125. package/lib/server/middleware/cors.ts +28 -4
  126. package/lib/server/middleware/errorHandler.test.ts +7 -5
  127. package/lib/server/middleware/errorHandler.ts +3 -8
  128. package/lib/server/middleware/index.ts +0 -1
  129. package/lib/server/middleware/logger.test.ts +10 -8
  130. package/lib/server/middleware/logger.ts +17 -29
  131. package/lib/server/migrateTemplates.ts +3 -3
  132. package/lib/server/pageCache.test.ts +76 -77
  133. package/lib/server/pageCache.ts +0 -1
  134. package/lib/server/projectContext.ts +5 -4
  135. package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
  136. package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
  137. package/lib/server/routes/api/cms.test.ts +26 -14
  138. package/lib/server/routes/api/cms.ts +9 -14
  139. package/lib/server/routes/api/colors.test.ts +2 -2
  140. package/lib/server/routes/api/components.ts +31 -35
  141. package/lib/server/routes/api/config.ts +3 -4
  142. package/lib/server/routes/api/core-routes.ts +49 -76
  143. package/lib/server/routes/api/enums.test.ts +2 -2
  144. package/lib/server/routes/api/functions.ts +9 -17
  145. package/lib/server/routes/api/index.ts +3 -6
  146. package/lib/server/routes/api/pages.ts +8 -11
  147. package/lib/server/routes/api/shared.test.ts +1 -1
  148. package/lib/server/routes/api/shared.ts +12 -9
  149. package/lib/server/routes/api/variables.test.ts +3 -5
  150. package/lib/server/routes/api/variables.ts +1 -1
  151. package/lib/server/routes/index.ts +25 -28
  152. package/lib/server/routes/pages.ts +35 -31
  153. package/lib/server/routes/static.ts +17 -6
  154. package/lib/server/runtime/bundler.ts +98 -61
  155. package/lib/server/runtime/fs.ts +16 -26
  156. package/lib/server/runtime/httpServer.ts +8 -12
  157. package/lib/server/services/ColorService.test.ts +3 -3
  158. package/lib/server/services/ColorService.ts +37 -29
  159. package/lib/server/services/EnumService.test.ts +4 -8
  160. package/lib/server/services/EnumService.ts +11 -3
  161. package/lib/server/services/VariableService.test.ts +8 -12
  162. package/lib/server/services/VariableService.ts +11 -3
  163. package/lib/server/services/cmsService.test.ts +158 -120
  164. package/lib/server/services/cmsService.ts +36 -146
  165. package/lib/server/services/componentService.test.ts +125 -45
  166. package/lib/server/services/componentService.ts +70 -46
  167. package/lib/server/services/configService.test.ts +22 -45
  168. package/lib/server/services/configService.ts +50 -27
  169. package/lib/server/services/fileWatcherService.ts +42 -8
  170. package/lib/server/services/index.ts +0 -1
  171. package/lib/server/services/pageService.test.ts +8 -10
  172. package/lib/server/services/pageService.ts +32 -18
  173. package/lib/server/ssr/attributeBuilder.ts +18 -8
  174. package/lib/server/ssr/buildErrorOverlay.ts +11 -12
  175. package/lib/server/ssr/clientDataInjector.ts +7 -21
  176. package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
  177. package/lib/server/ssr/cssCollector.ts +1 -1
  178. package/lib/server/ssr/errorOverlay.test.ts +1 -1
  179. package/lib/server/ssr/errorOverlay.ts +3 -9
  180. package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
  181. package/lib/server/ssr/htmlGenerator.test.ts +120 -44
  182. package/lib/server/ssr/htmlGenerator.ts +126 -91
  183. package/lib/server/ssr/imageMetadata.test.ts +3 -1
  184. package/lib/server/ssr/imageMetadata.ts +27 -21
  185. package/lib/server/ssr/jsCollector.test.ts +8 -18
  186. package/lib/server/ssr/jsCollector.ts +3 -8
  187. package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
  188. package/lib/server/ssr/metaTagGenerator.ts +2 -2
  189. package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
  190. package/lib/server/ssr/ssrRenderer.test.ts +316 -256
  191. package/lib/server/ssr/ssrRenderer.ts +795 -243
  192. package/lib/server/ssrRenderer.test.ts +1048 -954
  193. package/lib/server/utils/jsonLineMapper.test.ts +28 -28
  194. package/lib/server/utils/jsonLineMapper.ts +7 -7
  195. package/lib/server/validateStyleCoverage.ts +18 -21
  196. package/lib/server/websocketManager.ts +28 -19
  197. package/lib/shared/attributeNodeUtils.test.ts +15 -15
  198. package/lib/shared/attributeNodeUtils.ts +5 -12
  199. package/lib/shared/breakpoints.test.ts +5 -5
  200. package/lib/shared/breakpoints.ts +4 -11
  201. package/lib/shared/cmsQuery.test.ts +81 -0
  202. package/lib/shared/cmsQuery.ts +92 -0
  203. package/lib/shared/cmsQueryParser.test.ts +50 -42
  204. package/lib/shared/cmsQueryParser.ts +60 -38
  205. package/lib/shared/colorConversions.ts +9 -9
  206. package/lib/shared/colorVariableUtils.test.ts +27 -5
  207. package/lib/shared/colorVariableUtils.ts +21 -12
  208. package/lib/shared/componentRefs.ts +1 -5
  209. package/lib/shared/constants.test.ts +3 -3
  210. package/lib/shared/constants.ts +8 -8
  211. package/lib/shared/cssGeneration.test.ts +285 -144
  212. package/lib/shared/cssGeneration.ts +217 -531
  213. package/lib/shared/cssNamedColors.ts +152 -30
  214. package/lib/shared/cssProperties.test.ts +69 -70
  215. package/lib/shared/cssProperties.ts +298 -114
  216. package/lib/shared/elementClassName.test.ts +109 -109
  217. package/lib/shared/elementClassName.ts +3 -3
  218. package/lib/shared/elementUtils.ts +12 -16
  219. package/lib/shared/errorLogger.test.ts +12 -12
  220. package/lib/shared/errorLogger.ts +2 -10
  221. package/lib/shared/errors.test.ts +2 -13
  222. package/lib/shared/errors.ts +2 -8
  223. package/lib/shared/expressionEvaluator.test.ts +145 -0
  224. package/lib/shared/expressionEvaluator.ts +52 -24
  225. package/lib/shared/fontLoader.test.ts +32 -18
  226. package/lib/shared/fontLoader.ts +2 -2
  227. package/lib/shared/friendlyError.ts +2 -3
  228. package/lib/shared/gradientUtils.test.ts +3 -7
  229. package/lib/shared/gradientUtils.ts +17 -14
  230. package/lib/shared/hrefRefs.test.ts +2 -2
  231. package/lib/shared/hrefRefs.ts +2 -10
  232. package/lib/shared/i18n.test.ts +4 -4
  233. package/lib/shared/i18n.ts +18 -38
  234. package/lib/shared/index.ts +27 -0
  235. package/lib/shared/inlineSvgStyleRules.ts +14 -13
  236. package/lib/shared/interactiveStyleMappings.test.ts +32 -54
  237. package/lib/shared/interactiveStyleMappings.ts +11 -24
  238. package/lib/shared/interactiveStyles.test.ts +165 -188
  239. package/lib/shared/interfaces/contentProvider.ts +1 -1
  240. package/lib/shared/itemTemplateUtils.test.ts +11 -17
  241. package/lib/shared/itemTemplateUtils.ts +27 -39
  242. package/lib/shared/jsonRepair.ts +16 -10
  243. package/lib/shared/libraryLoader.test.ts +21 -55
  244. package/lib/shared/libraryLoader.ts +7 -22
  245. package/lib/shared/linkUtils.ts +1 -1
  246. package/lib/shared/logger.test.ts +66 -0
  247. package/lib/shared/logger.ts +94 -0
  248. package/lib/shared/markdown.ts +25 -0
  249. package/lib/shared/netlifyLocale404.test.ts +179 -0
  250. package/lib/shared/netlifyLocale404.ts +110 -0
  251. package/lib/shared/nodeUtils.test.ts +28 -16
  252. package/lib/shared/nodeUtils.ts +76 -23
  253. package/lib/shared/pathArrayUtils.test.ts +1 -2
  254. package/lib/shared/pathArrayUtils.ts +1 -1
  255. package/lib/shared/pathSecurity.ts +2 -2
  256. package/lib/shared/pathUtils.test.ts +4 -6
  257. package/lib/shared/pathUtils.ts +42 -49
  258. package/lib/shared/paths/Path.test.ts +2 -2
  259. package/lib/shared/paths/Path.ts +0 -1
  260. package/lib/shared/paths/PathConverter.test.ts +1 -1
  261. package/lib/shared/paths/PathConverter.ts +17 -20
  262. package/lib/shared/paths/PathUtils.ts +13 -13
  263. package/lib/shared/paths/PathValidator.test.ts +2 -15
  264. package/lib/shared/paths/PathValidator.ts +12 -10
  265. package/lib/shared/paths/index.ts +1 -2
  266. package/lib/shared/permissions.test.ts +168 -0
  267. package/lib/shared/permissions.ts +162 -0
  268. package/lib/shared/propResolver.test.ts +240 -244
  269. package/lib/shared/propResolver.ts +15 -26
  270. package/lib/shared/pxToRem.test.ts +7 -6
  271. package/lib/shared/pxToRem.ts +2 -5
  272. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
  273. package/lib/shared/registry/ClientRegistry.ts +0 -2
  274. package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
  275. package/lib/shared/registry/ComponentRegistry.ts +12 -9
  276. package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
  277. package/lib/shared/registry/RegistryManager.ts +1 -2
  278. package/lib/shared/registry/SSRRegistry.ts +0 -2
  279. package/lib/shared/registry/createNodeType.ts +7 -9
  280. package/lib/shared/registry/defineNodeType.ts +2 -6
  281. package/lib/shared/registry/fieldPresets.ts +3 -1
  282. package/lib/shared/registry/index.ts +0 -1
  283. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
  284. package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
  285. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
  286. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
  287. package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
  288. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
  289. package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
  290. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
  291. package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
  292. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
  293. package/lib/shared/registry/nodeTypes/index.ts +26 -3
  294. package/lib/shared/responsiveScaling.test.ts +16 -34
  295. package/lib/shared/responsiveScaling.ts +61 -42
  296. package/lib/shared/responsiveStyleUtils.test.ts +0 -1
  297. package/lib/shared/responsiveStyleUtils.ts +11 -13
  298. package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
  299. package/lib/shared/richtext/htmlToTiptap.ts +2 -4
  300. package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
  301. package/lib/shared/richtext/types.ts +1 -8
  302. package/lib/shared/slugTranslator.test.ts +13 -13
  303. package/lib/shared/slugTranslator.ts +12 -16
  304. package/lib/shared/slugify.ts +9 -15
  305. package/lib/shared/styleNodeUtils.test.ts +8 -8
  306. package/lib/shared/styleNodeUtils.ts +18 -20
  307. package/lib/shared/styleUtils.test.ts +87 -61
  308. package/lib/shared/styleUtils.ts +5 -6
  309. package/lib/shared/themeDefaults.test.ts +11 -14
  310. package/lib/shared/themeDefaults.ts +3 -4
  311. package/lib/shared/tree/PathBuilder.test.ts +63 -145
  312. package/lib/shared/tree/PathBuilder.ts +59 -47
  313. package/lib/shared/treePathUtils.test.ts +51 -12
  314. package/lib/shared/treePathUtils.ts +91 -60
  315. package/lib/shared/types/api.ts +105 -8
  316. package/lib/shared/types/cms.test.ts +34 -0
  317. package/lib/shared/types/cms.ts +90 -34
  318. package/lib/shared/types/comment.ts +49 -16
  319. package/lib/shared/types/components.ts +51 -25
  320. package/lib/shared/types/errors.test.ts +1 -6
  321. package/lib/shared/types/errors.ts +3 -7
  322. package/lib/shared/types/experiments.ts +28 -28
  323. package/lib/shared/types/index.ts +25 -2
  324. package/lib/shared/types/permissions.ts +139 -0
  325. package/lib/shared/types/styles.ts +0 -1
  326. package/lib/shared/types/variables.test.ts +4 -13
  327. package/lib/shared/types/variables.ts +51 -30
  328. package/lib/shared/types.ts +1 -2
  329. package/lib/shared/utilityClassConfig.ts +751 -321
  330. package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
  331. package/lib/shared/utilityClassMapper.test.ts +433 -95
  332. package/lib/shared/utilityClassMapper.ts +322 -249
  333. package/lib/shared/utilityClassNames.test.ts +38 -0
  334. package/lib/shared/utilityClassNames.ts +458 -0
  335. package/lib/shared/utils.test.ts +2 -10
  336. package/lib/shared/utils.ts +19 -10
  337. package/lib/shared/validation/cmsValidators.ts +2 -1
  338. package/lib/shared/validation/commentValidators.test.ts +53 -0
  339. package/lib/shared/validation/commentValidators.ts +12 -1
  340. package/lib/shared/validation/index.ts +1 -0
  341. package/lib/shared/validation/permissionsValidators.test.ts +49 -0
  342. package/lib/shared/validation/permissionsValidators.ts +49 -0
  343. package/lib/shared/validation/propValidator.test.ts +19 -21
  344. package/lib/shared/validation/propValidator.ts +13 -18
  345. package/lib/shared/validation/schemas.test.ts +64 -32
  346. package/lib/shared/validation/schemas.ts +616 -345
  347. package/lib/shared/validation/validators.test.ts +3 -8
  348. package/lib/shared/validation/validators.ts +89 -68
  349. package/lib/shared/viewportUnits.integration.test.ts +14 -10
  350. package/lib/shared/viewportUnits.test.ts +24 -23
  351. package/lib/shared/viewportUnits.ts +12 -5
  352. package/lib/test-utils/dom-setup.ts +1 -1
  353. package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
  354. package/lib/test-utils/factories/DomMockFactory.ts +17 -23
  355. package/lib/test-utils/factories/EventMockFactory.ts +7 -13
  356. package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
  357. package/lib/test-utils/factories/ServerMockFactory.ts +6 -10
  358. package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
  359. package/lib/test-utils/fixtures.ts +45 -45
  360. package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
  361. package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
  362. package/lib/test-utils/helpers.ts +1 -5
  363. package/lib/test-utils/index.ts +0 -4
  364. package/lib/test-utils/mockFactories.ts +13 -19
  365. package/lib/test-utils/mocks.ts +6 -4
  366. package/package.json +3 -5
  367. package/scripts/build-for-publish.mjs +2 -4
  368. package/scripts/build-meno-filter.ts +4 -7
  369. package/tsconfig.json +1 -0
  370. package/vite.config.ts +4 -4
  371. package/build-next.ts +0 -1361
  372. package/build-static.test.ts +0 -424
  373. package/build-static.ts +0 -1074
  374. package/dist/build-static.js +0 -36
  375. package/dist/chunks/chunk-2MHDV5BF.js +0 -251
  376. package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
  377. package/dist/chunks/chunk-AZQYF6KE.js +0 -559
  378. package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
  379. package/dist/chunks/chunk-GZHGVVW3.js +0 -322
  380. package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
  381. package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
  382. package/dist/chunks/chunk-I7YIGZXT.js +0 -467
  383. package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
  384. package/dist/chunks/chunk-IGYR22T6.js +0 -6192
  385. package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
  386. package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
  387. package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
  388. package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
  389. package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
  390. package/dist/chunks/chunk-QB2LNO4W.js +0 -77
  391. package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
  392. package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
  393. package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
  394. package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
  395. package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
  396. package/dist/chunks/chunk-X754AHS5.js.map +0 -7
  397. package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
  398. package/dist/chunks/configService-R3OGU2UD.js +0 -13
  399. package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
  400. package/dist/chunks/constants-STK2YBIW.js +0 -46
  401. package/dist/chunks/constants-STK2YBIW.js.map +0 -7
  402. package/dist/chunks/fs-JGINUXGL.js.map +0 -7
  403. package/dist/entries/server-router.js +0 -67
  404. package/dist/entries/server-router.js.map +0 -7
  405. package/entries/server-router.tsx +0 -81
  406. package/lib/server/providers/fileSystemPageProvider.ts +0 -160
  407. package/lib/server/webflow/buildWebflow.ts +0 -635
  408. package/lib/server/webflow/index.ts +0 -23
  409. package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
  410. package/lib/server/webflow/nodeToWebflow.ts +0 -2435
  411. package/lib/server/webflow/styleMapper.test.ts +0 -389
  412. package/lib/server/webflow/styleMapper.ts +0 -695
  413. package/lib/server/webflow/templateWrapper.ts +0 -49
  414. package/lib/server/webflow/types.ts +0 -396
  415. /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
@@ -52,7 +52,7 @@ export function richTextMarkerToHtml(marker: RichTextMarker): string {
52
52
  */
53
53
  function wrapRichTextProps(
54
54
  props: Record<string, unknown>,
55
- propDefs: Record<string, PropDefinition>
55
+ propDefs: Record<string, PropDefinition>,
56
56
  ): Record<string, unknown> {
57
57
  const result = { ...props };
58
58
 
@@ -100,39 +100,35 @@ export interface ResolvePropsOptions {
100
100
  /**
101
101
  * Resolves component props by applying defaults and merging with passed props
102
102
  * Now includes validation for type safety
103
- *
103
+ *
104
104
  * @param options - Object containing prop definitions, passed props, and children
105
105
  * @returns Resolved props object with defaults applied and validated
106
106
  */
107
107
  export function resolveComponentProps(options: ResolvePropsOptions): Record<string, unknown> {
108
108
  const { propDefs, passedProps, children = [], locale, i18nConfig } = options;
109
-
109
+
110
110
  // Validate props against interface definition
111
111
  // This provides runtime type checking while maintaining backward compatibility
112
112
  try {
113
113
  const validationResult = validateComponentProps(propDefs, passedProps);
114
-
114
+
115
115
  if (!validationResult.valid && validationResult.errors.length > 0) {
116
116
  // Log validation errors but continue (graceful degradation)
117
117
  }
118
-
118
+
119
119
  // Use validated props (includes coerced values and defaults)
120
120
  const validatedProps = validationResult.props;
121
-
121
+
122
122
  // Handle children prop separately (not validated by prop validator)
123
123
  const resolvedProps: Record<string, unknown> = { ...validatedProps };
124
-
124
+
125
125
  // Apply children handling
126
126
  if ('children' in propDefs) {
127
127
  const childrenPropDef = propDefs.children;
128
128
  if (childrenPropDef && typeof childrenPropDef === 'object' && 'default' in childrenPropDef) {
129
- resolvedProps.children = Array.isArray(children) && children.length > 0
130
- ? children
131
- : childrenPropDef.default;
129
+ resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : childrenPropDef.default;
132
130
  } else {
133
- resolvedProps.children = Array.isArray(children) && children.length > 0
134
- ? children
135
- : undefined;
131
+ resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : undefined;
136
132
  }
137
133
  } else if (Array.isArray(children) && children.length > 0) {
138
134
  // Children passed but not in interface - allow it (backward compatibility)
@@ -150,27 +146,21 @@ export function resolveComponentProps(options: ResolvePropsOptions): Record<stri
150
146
  // Wrap rich-text props in marker objects for HTML rendering
151
147
  // Must happen AFTER i18n resolution so HTML strings get properly wrapped
152
148
  return wrapRichTextProps(result, propDefs);
153
- } catch (error) {
149
+ } catch (_error) {
154
150
  // Fallback to original behavior if validation fails (backward compatibility)
155
151
  const resolvedProps: Record<string, unknown> = {};
156
-
152
+
157
153
  // Apply defaults and passed props (original logic)
158
154
  for (const [propName, propDef] of Object.entries(propDefs)) {
159
155
  if (propDef && typeof propDef === 'object' && 'default' in propDef) {
160
156
  if (propName === 'children') {
161
- resolvedProps.children = Array.isArray(children) && children.length > 0
162
- ? children
163
- : propDef.default;
157
+ resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : propDef.default;
164
158
  } else {
165
- resolvedProps[propName] = passedProps[propName] !== undefined
166
- ? passedProps[propName]
167
- : propDef.default;
159
+ resolvedProps[propName] = passedProps[propName] !== undefined ? passedProps[propName] : propDef.default;
168
160
  }
169
161
  } else {
170
162
  if (propName === 'children') {
171
- resolvedProps.children = Array.isArray(children) && children.length > 0
172
- ? children
173
- : undefined;
163
+ resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : undefined;
174
164
  } else {
175
165
  resolvedProps[propName] = passedProps[propName];
176
166
  }
@@ -197,7 +187,7 @@ export function resolvePropsFromDefinition(
197
187
  passedProps: Record<string, unknown> = {},
198
188
  children: Array<ComponentNode | string> | string | ComponentNode | null | undefined = [],
199
189
  locale?: string,
200
- i18nConfig?: I18nConfig
190
+ i18nConfig?: I18nConfig,
201
191
  ): Record<string, unknown> {
202
192
  const propDefs = componentDef.interface || {};
203
193
  return resolveComponentProps({
@@ -208,4 +198,3 @@ export function resolvePropsFromDefinition(
208
198
  i18nConfig,
209
199
  });
210
200
  }
211
-
@@ -90,14 +90,14 @@ describe('applyRemConversion', () => {
90
90
  });
91
91
 
92
92
  test('handles multiple declarations', () => {
93
- expect(applyRemConversion('padding: 16px; margin: 8px;', enabledConfig))
94
- .toBe('padding: 1rem; margin: 0.5rem');
93
+ expect(applyRemConversion('padding: 16px; margin: 8px;', enabledConfig)).toBe('padding: 1rem; margin: 0.5rem');
95
94
  });
96
95
 
97
96
  test('preserves excluded properties', () => {
98
97
  expect(applyRemConversion('border-width: 1px;', enabledConfig)).toBe('border-width: 1px');
99
- expect(applyRemConversion('box-shadow: 0 1px 2px rgba(0,0,0,0.1);', enabledConfig))
100
- .toBe('box-shadow: 0 1px 2px rgba(0,0,0,0.1)');
98
+ expect(applyRemConversion('box-shadow: 0 1px 2px rgba(0,0,0,0.1);', enabledConfig)).toBe(
99
+ 'box-shadow: 0 1px 2px rgba(0,0,0,0.1)',
100
+ );
101
101
  });
102
102
 
103
103
  test('returns unchanged when disabled', () => {
@@ -109,7 +109,8 @@ describe('applyRemConversion', () => {
109
109
  });
110
110
 
111
111
  test('handles mixed convertible and non-convertible', () => {
112
- expect(applyRemConversion('padding: 16px; border-width: 1px; margin: 8px;', enabledConfig))
113
- .toBe('padding: 1rem; border-width: 1px; margin: 0.5rem');
112
+ expect(applyRemConversion('padding: 16px; border-width: 1px; margin: 8px;', enabledConfig)).toBe(
113
+ 'padding: 1rem; border-width: 1px; margin: 0.5rem',
114
+ );
114
115
  });
115
116
  });
@@ -50,15 +50,12 @@ export function shouldConvertProperty(cssProperty: string): boolean {
50
50
  * Apply rem conversion to a CSS declarations string (e.g. "padding: 16px; font-size: 18px").
51
51
  * Checks each property against the exclusion list before converting.
52
52
  */
53
- export function applyRemConversion(
54
- declarations: string,
55
- remConfig?: RemConversionConfig
56
- ): string {
53
+ export function applyRemConversion(declarations: string, remConfig?: RemConversionConfig): string {
57
54
  if (!remConfig?.enabled) return declarations;
58
55
 
59
56
  return declarations
60
57
  .split(';')
61
- .map(decl => {
58
+ .map((decl) => {
62
59
  const trimmed = decl.trim();
63
60
  if (!trimmed) return '';
64
61
  const colonIndex = trimmed.indexOf(':');
@@ -4,7 +4,6 @@
4
4
 
5
5
  import { describe, it, expect, beforeEach } from 'bun:test';
6
6
  import { ClientNodeTypeRegistry } from './ClientNodeTypeRegistry';
7
- import { SSRNodeTypeRegistry } from './SSRNodeTypeRegistry';
8
7
  import { NodeTypeManager, globalNodeTypeManager } from './NodeTypeManager';
9
8
  import { defineNodeType } from './defineNodeType';
10
9
  import { registerBuiltInNodeTypes, builtInNodeTypes } from './nodeTypes';
@@ -42,10 +41,11 @@ describe('BaseNodeTypeRegistry', () => {
42
41
  describe('registerAll', () => {
43
42
  it('should register multiple node type definitions', () => {
44
43
  registry.registerAll(builtInNodeTypes);
45
- expect(registry.size).toBe(7); // 7 node types after cms-list merged into list
44
+ expect(registry.size).toBe(10); // node, component, slot, embed, link, locale-list, list, island, markdown, custom
46
45
  expect(registry.has(NODE_TYPE.NODE)).toBe(true);
47
46
  expect(registry.has(NODE_TYPE.COMPONENT)).toBe(true);
48
47
  expect(registry.has(NODE_TYPE.EMBED)).toBe(true);
48
+ expect(registry.has(NODE_TYPE.ISLAND)).toBe(true);
49
49
  });
50
50
  });
51
51
 
@@ -136,14 +136,18 @@ describe('BaseNodeTypeRegistry', () => {
136
136
  describe('subscribe', () => {
137
137
  it('should notify listeners on registration', () => {
138
138
  let called = false;
139
- registry.subscribe(() => { called = true; });
139
+ registry.subscribe(() => {
140
+ called = true;
141
+ });
140
142
  registry.registerAll(builtInNodeTypes);
141
143
  expect(called).toBe(true);
142
144
  });
143
145
 
144
146
  it('should allow unsubscribing', () => {
145
147
  let callCount = 0;
146
- const unsubscribe = registry.subscribe(() => { callCount++; });
148
+ const unsubscribe = registry.subscribe(() => {
149
+ callCount++;
150
+ });
147
151
  registry.registerAll(builtInNodeTypes);
148
152
  expect(callCount).toBe(1);
149
153
 
@@ -161,7 +165,7 @@ describe('BaseNodeTypeRegistry', () => {
161
165
  it('should filter by category', () => {
162
166
  const coreTypes = registry.getByCategory('core');
163
167
  expect(coreTypes.length).toBeGreaterThan(0);
164
- expect(coreTypes.every(t => t.category === 'core')).toBe(true);
168
+ expect(coreTypes.every((t) => t.category === 'core')).toBe(true);
165
169
  });
166
170
  });
167
171
  });
@@ -185,6 +189,8 @@ describe('globalNodeTypeManager', () => {
185
189
  registerBuiltInNodeTypes();
186
190
  expect(globalNodeTypeManager.has(NODE_TYPE.NODE)).toBe(true);
187
191
  expect(globalNodeTypeManager.has(NODE_TYPE.EMBED)).toBe(true);
188
- expect(globalNodeTypeManager.getAll().length).toBe(7); // 7 node types after cms-list merged into list
192
+ expect(globalNodeTypeManager.has(NODE_TYPE.ISLAND)).toBe(true);
193
+ expect(globalNodeTypeManager.has(NODE_TYPE.MARKDOWN)).toBe(true);
194
+ expect(globalNodeTypeManager.getAll().length).toBe(10); // node, component, slot, embed, link, locale-list, list, island, markdown, custom
189
195
  });
190
196
  });
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { BaseComponentRegistry } from './ComponentRegistry';
7
- import type { ComponentDefinition } from '../types';
8
7
 
9
8
  export class ClientRegistry extends BaseComponentRegistry {
10
9
  /**
@@ -12,4 +11,3 @@ export class ClientRegistry extends BaseComponentRegistry {
12
11
  * For now, it's the same as base registry
13
12
  */
14
13
  }
15
-
@@ -15,7 +15,7 @@ describe('BaseComponentRegistry', () => {
15
15
  describe('register', () => {
16
16
  test('registers a component', () => {
17
17
  const component: ComponentDefinition = {
18
- component: { structure: { type: 'node' as const, tag: 'div' } }
18
+ component: { structure: { type: 'node' as const, tag: 'div' } },
19
19
  };
20
20
 
21
21
  registry.register('Button', component);
@@ -26,10 +26,10 @@ describe('BaseComponentRegistry', () => {
26
26
 
27
27
  test('overwrites existing component', () => {
28
28
  const component1: ComponentDefinition = {
29
- component: { structure: { type: 'node' as const, tag: 'div' } }
29
+ component: { structure: { type: 'node' as const, tag: 'div' } },
30
30
  };
31
31
  const component2: ComponentDefinition = {
32
- component: { structure: { type: 'node' as const, tag: 'span' } }
32
+ component: { structure: { type: 'node' as const, tag: 'span' } },
33
33
  };
34
34
 
35
35
  registry.register('Button', component1);
@@ -42,7 +42,7 @@ describe('BaseComponentRegistry', () => {
42
42
  describe('get', () => {
43
43
  test('returns component by name', () => {
44
44
  const component: ComponentDefinition = {
45
- component: { structure: { type: 'node' as const, tag: 'div' } }
45
+ component: { structure: { type: 'node' as const, tag: 'div' } },
46
46
  };
47
47
 
48
48
  registry.register('Button', component);
@@ -58,7 +58,7 @@ describe('BaseComponentRegistry', () => {
58
58
  describe('has', () => {
59
59
  test('returns true for registered component', () => {
60
60
  const component: ComponentDefinition = {
61
- component: { structure: { type: 'node' as const, tag: 'div' } }
61
+ component: { structure: { type: 'node' as const, tag: 'div' } },
62
62
  };
63
63
 
64
64
  registry.register('Button', component);
@@ -74,10 +74,10 @@ describe('BaseComponentRegistry', () => {
74
74
  describe('clear', () => {
75
75
  test('removes all components', () => {
76
76
  const component1: ComponentDefinition = {
77
- component: { structure: { type: 'node' as const, tag: 'div' } }
77
+ component: { structure: { type: 'node' as const, tag: 'div' } },
78
78
  };
79
79
  const component2: ComponentDefinition = {
80
- component: { structure: { type: 'node' as const, tag: 'span' } }
80
+ component: { structure: { type: 'node' as const, tag: 'span' } },
81
81
  };
82
82
 
83
83
  registry.register('Button', component1);
@@ -94,8 +94,8 @@ describe('BaseComponentRegistry', () => {
94
94
  describe('merge', () => {
95
95
  test('merges multiple components', () => {
96
96
  const components: Record<string, ComponentDefinition> = {
97
- 'Button': { component: { structure: { type: 'node' as const, tag: 'button' } } },
98
- 'Card': { component: { structure: { type: 'node' as const, tag: 'div' } } }
97
+ Button: { component: { structure: { type: 'node' as const, tag: 'button' } } },
98
+ Card: { component: { structure: { type: 'node' as const, tag: 'div' } } },
99
99
  };
100
100
 
101
101
  registry.merge(components);
@@ -106,14 +106,14 @@ describe('BaseComponentRegistry', () => {
106
106
 
107
107
  test('overwrites existing components', () => {
108
108
  const component1: ComponentDefinition = {
109
- component: { structure: { type: 'node' as const, tag: 'div' } }
109
+ component: { structure: { type: 'node' as const, tag: 'div' } },
110
110
  };
111
111
  const component2: ComponentDefinition = {
112
- component: { structure: { type: 'node' as const, tag: 'button' } }
112
+ component: { structure: { type: 'node' as const, tag: 'button' } },
113
113
  };
114
114
 
115
115
  registry.register('Button', component1);
116
- registry.merge({ 'Button': component2 });
116
+ registry.merge({ Button: component2 });
117
117
 
118
118
  expect(registry.get('Button')).toEqual(component2);
119
119
  });
@@ -122,10 +122,10 @@ describe('BaseComponentRegistry', () => {
122
122
  describe('getAll', () => {
123
123
  test('returns all registered components', () => {
124
124
  const component1: ComponentDefinition = {
125
- component: { structure: { type: 'node' as const, tag: 'button' } }
125
+ component: { structure: { type: 'node' as const, tag: 'button' } },
126
126
  };
127
127
  const component2: ComponentDefinition = {
128
- component: { structure: { type: 'node' as const, tag: 'div' } }
128
+ component: { structure: { type: 'node' as const, tag: 'div' } },
129
129
  };
130
130
 
131
131
  registry.register('Button', component1);
@@ -133,20 +133,20 @@ describe('BaseComponentRegistry', () => {
133
133
 
134
134
  const all = registry.getAll();
135
135
 
136
- expect(all['Button']).toEqual(component1);
137
- expect(all['Card']).toEqual(component2);
136
+ expect(all.Button).toEqual(component1);
137
+ expect(all.Card).toEqual(component2);
138
138
  expect(Object.keys(all).length).toBe(2);
139
139
  });
140
140
 
141
141
  test('returns copy of registry', () => {
142
142
  const component: ComponentDefinition = {
143
- component: { structure: { type: 'node' as const, tag: 'button' } }
143
+ component: { structure: { type: 'node' as const, tag: 'button' } },
144
144
  };
145
145
 
146
146
  registry.register('Button', component);
147
147
 
148
148
  const all = registry.getAll();
149
- delete all['Button'];
149
+ delete all.Button;
150
150
 
151
151
  expect(registry.has('Button')).toBe(true);
152
152
  });
@@ -159,10 +159,10 @@ describe('BaseComponentRegistry', () => {
159
159
  describe('getNames', () => {
160
160
  test('returns list of component names', () => {
161
161
  const component1: ComponentDefinition = {
162
- component: { structure: { type: 'node' as const, tag: 'button' } }
162
+ component: { structure: { type: 'node' as const, tag: 'button' } },
163
163
  };
164
164
  const component2: ComponentDefinition = {
165
- component: { structure: { type: 'node' as const, tag: 'div' } }
165
+ component: { structure: { type: 'node' as const, tag: 'div' } },
166
166
  };
167
167
 
168
168
  registry.register('Button', component1);
@@ -183,7 +183,7 @@ describe('BaseComponentRegistry', () => {
183
183
  describe('remove', () => {
184
184
  test('removes component and returns true', () => {
185
185
  const component: ComponentDefinition = {
186
- component: { structure: { type: 'node' as const, tag: 'button' } }
186
+ component: { structure: { type: 'node' as const, tag: 'button' } },
187
187
  };
188
188
 
189
189
  registry.register('Button', component);
@@ -204,12 +204,14 @@ describe('BaseComponentRegistry', () => {
204
204
  describe('subscribe', () => {
205
205
  test('notifies listeners on register', () => {
206
206
  let called = false;
207
- const listener = () => { called = true; };
207
+ const listener = () => {
208
+ called = true;
209
+ };
208
210
 
209
211
  registry.subscribe(listener);
210
212
 
211
213
  const component: ComponentDefinition = {
212
- component: { structure: { type: 'node' as const, tag: 'button' } }
214
+ component: { structure: { type: 'node' as const, tag: 'button' } },
213
215
  };
214
216
  registry.register('Button', component);
215
217
 
@@ -218,7 +220,9 @@ describe('BaseComponentRegistry', () => {
218
220
 
219
221
  test('notifies listeners on clear', () => {
220
222
  let called = false;
221
- const listener = () => { called = true; };
223
+ const listener = () => {
224
+ called = true;
225
+ };
222
226
 
223
227
  registry.subscribe(listener);
224
228
 
@@ -229,7 +233,9 @@ describe('BaseComponentRegistry', () => {
229
233
 
230
234
  test('notifies listeners on merge', () => {
231
235
  let called = false;
232
- const listener = () => { called = true; };
236
+ const listener = () => {
237
+ called = true;
238
+ };
233
239
 
234
240
  registry.subscribe(listener);
235
241
 
@@ -241,12 +247,14 @@ describe('BaseComponentRegistry', () => {
241
247
  test('notifies listeners on remove', () => {
242
248
  let called = false;
243
249
  const component: ComponentDefinition = {
244
- component: { structure: { type: 'node' as const, tag: 'button' } }
250
+ component: { structure: { type: 'node' as const, tag: 'button' } },
245
251
  };
246
252
 
247
253
  registry.register('Button', component);
248
254
 
249
- const listener = () => { called = true; };
255
+ const listener = () => {
256
+ called = true;
257
+ };
250
258
  registry.subscribe(listener);
251
259
 
252
260
  registry.remove('Button');
@@ -256,12 +264,14 @@ describe('BaseComponentRegistry', () => {
256
264
 
257
265
  test('returns unsubscribe function', () => {
258
266
  let callCount = 0;
259
- const listener = () => { callCount++; };
267
+ const listener = () => {
268
+ callCount++;
269
+ };
260
270
 
261
271
  const unsubscribe = registry.subscribe(listener);
262
272
 
263
273
  const component: ComponentDefinition = {
264
- component: { structure: { type: 'node' as const, tag: 'button' } }
274
+ component: { structure: { type: 'node' as const, tag: 'button' } },
265
275
  };
266
276
  registry.register('Button', component);
267
277
 
@@ -275,14 +285,18 @@ describe('BaseComponentRegistry', () => {
275
285
  test('handles multiple listeners', () => {
276
286
  let count1 = 0;
277
287
  let count2 = 0;
278
- const listener1 = () => { count1++; };
279
- const listener2 = () => { count2++; };
288
+ const listener1 = () => {
289
+ count1++;
290
+ };
291
+ const listener2 = () => {
292
+ count2++;
293
+ };
280
294
 
281
295
  registry.subscribe(listener1);
282
296
  registry.subscribe(listener2);
283
297
 
284
298
  const component: ComponentDefinition = {
285
- component: { structure: { type: 'node' as const, tag: 'button' } }
299
+ component: { structure: { type: 'node' as const, tag: 'button' } },
286
300
  };
287
301
  registry.register('Button', component);
288
302
 
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import type { ComponentDefinition } from '../types';
8
+ import { logRuntimeError } from '../errorLogger';
8
9
 
9
10
  /**
10
11
  * Base registry class with common functionality
@@ -12,7 +13,7 @@ import type { ComponentDefinition } from '../types';
12
13
  export abstract class BaseComponentRegistry {
13
14
  protected registry: Record<string, ComponentDefinition> = {};
14
15
  private listeners: Set<() => void> = new Set();
15
-
16
+
16
17
  /**
17
18
  * Register a component with the given name
18
19
  */
@@ -20,21 +21,21 @@ export abstract class BaseComponentRegistry {
20
21
  this.registry[name] = definition;
21
22
  this.notify();
22
23
  }
23
-
24
+
24
25
  /**
25
26
  * Get a component by name
26
27
  */
27
28
  get(name: string): ComponentDefinition | undefined {
28
29
  return this.registry[name];
29
30
  }
30
-
31
+
31
32
  /**
32
33
  * Check if a component exists
33
34
  */
34
35
  has(name: string): boolean {
35
36
  return name in this.registry;
36
37
  }
37
-
38
+
38
39
  /**
39
40
  * Clear all registered components
40
41
  */
@@ -42,7 +43,7 @@ export abstract class BaseComponentRegistry {
42
43
  this.registry = {};
43
44
  this.notify();
44
45
  }
45
-
46
+
46
47
  /**
47
48
  * Merge components into the registry
48
49
  * Existing components with the same name will be overwritten
@@ -51,21 +52,21 @@ export abstract class BaseComponentRegistry {
51
52
  Object.assign(this.registry, components);
52
53
  this.notify();
53
54
  }
54
-
55
+
55
56
  /**
56
57
  * Get all registered components
57
58
  */
58
59
  getAll(): Record<string, ComponentDefinition> {
59
60
  return { ...this.registry };
60
61
  }
61
-
62
+
62
63
  /**
63
64
  * Get list of registered component names
64
65
  */
65
66
  getNames(): string[] {
66
67
  return Object.keys(this.registry);
67
68
  }
68
-
69
+
69
70
  /**
70
71
  * Remove a component by name
71
72
  */
@@ -93,8 +94,10 @@ export abstract class BaseComponentRegistry {
93
94
  try {
94
95
  listener();
95
96
  } catch (err) {
97
+ // One throwing subscriber must not stop the rest from being notified, but
98
+ // a swallowed listener error hides real store-update bugs — surface it.
99
+ logRuntimeError('ComponentRegistry.notify', err);
96
100
  }
97
101
  }
98
102
  }
99
103
  }
100
-
@@ -6,12 +6,22 @@
6
6
  import type { ReactElement } from 'react';
7
7
  import type { ZodType } from 'zod';
8
8
  import type { ComponentNode } from '../types/nodes';
9
- import type { StyleValue } from '../types/styles';
10
9
 
11
10
  /**
12
11
  * Tree icon types for node display
13
12
  */
14
- export type TreeIcon = 'TEXT' | 'COMPONENT' | 'HTML_ELEMENT' | 'IMAGE' | 'OBJECT' | 'SLOT_MARKER' | 'ARRAY' | 'UNKNOWN' | 'FORM' | 'LINK';
13
+ export type TreeIcon =
14
+ | 'TEXT'
15
+ | 'COMPONENT'
16
+ | 'HTML_ELEMENT'
17
+ | 'IMAGE'
18
+ | 'OBJECT'
19
+ | 'SLOT_MARKER'
20
+ | 'ARRAY'
21
+ | 'UNKNOWN'
22
+ | 'FORM'
23
+ | 'LINK'
24
+ | 'CODE';
15
25
 
16
26
  /**
17
27
  * Node category for grouping in command palette
@@ -83,13 +93,13 @@ export interface ClientRenderContext {
83
93
  children: Array<ComponentNode | string> | string | undefined,
84
94
  elementPath: (string | number)[],
85
95
  parentComponentName?: string | null,
86
- componentContext?: string | null
96
+ componentContext?: string | null,
87
97
  ) => ReactElement | ReactElement[] | string | number | null;
88
98
  registerElement: (
89
99
  path: (string | number)[],
90
100
  element: HTMLElement | null,
91
101
  parentComponentName?: string | null,
92
- isComponentRoot?: boolean
102
+ isComponentRoot?: boolean,
93
103
  ) => void;
94
104
  getComponentDefinition: (name: string) => unknown | undefined;
95
105
  processI18n: (value: unknown) => string;
@@ -121,16 +131,13 @@ export interface SSRRenderContext {
121
131
  */
122
132
  export type ClientNodeRenderer<TNode extends ComponentNode> = (
123
133
  node: TNode,
124
- context: ClientRenderContext
134
+ context: ClientRenderContext,
125
135
  ) => ReactElement | null;
126
136
 
127
137
  /**
128
138
  * SSR renderer function type
129
139
  */
130
- export type SSRNodeRenderer<TNode extends ComponentNode> = (
131
- node: TNode,
132
- context: SSRRenderContext
133
- ) => string;
140
+ export type SSRNodeRenderer<TNode extends ComponentNode> = (node: TNode, context: SSRRenderContext) => string;
134
141
 
135
142
  /**
136
143
  * Props editor component props
@@ -36,7 +36,7 @@ export class RegistryManager {
36
36
  sync(from: 'client' | 'ssr', to: 'client' | 'ssr'): void {
37
37
  const source = from === 'client' ? this.clientRegistry : this.ssrRegistry;
38
38
  const target = to === 'client' ? this.clientRegistry : this.ssrRegistry;
39
-
39
+
40
40
  const components = source.getAll();
41
41
  target.merge(components);
42
42
  }
@@ -57,4 +57,3 @@ export class RegistryManager {
57
57
  this.ssrRegistry.clear();
58
58
  }
59
59
  }
60
-
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { BaseComponentRegistry } from './ComponentRegistry';
7
- import type { ComponentDefinition } from '../types';
8
7
 
9
8
  export class SSRRegistry extends BaseComponentRegistry {
10
9
  /**
@@ -12,4 +11,3 @@ export class SSRRegistry extends BaseComponentRegistry {
12
11
  * For now, it's the same as base registry
13
12
  */
14
13
  }
15
-
@@ -33,10 +33,7 @@ const DEFAULT_CAPABILITIES: NodeCapabilities = {
33
33
  */
34
34
  function createTypeGuard<T>(typeValue: string) {
35
35
  return (node: unknown): node is T =>
36
- node !== null &&
37
- typeof node === 'object' &&
38
- 'type' in node &&
39
- (node as { type: unknown }).type === typeValue;
36
+ node !== null && typeof node === 'object' && 'type' in node && (node as { type: unknown }).type === typeValue;
40
37
  }
41
38
 
42
39
  /**
@@ -118,7 +115,7 @@ export interface CreateNodeTypeInput<TSchema extends ZodType> {
118
115
  * ```
119
116
  */
120
117
  export function createNodeType<TSchema extends ZodType>(
121
- input: CreateNodeTypeInput<TSchema>
118
+ input: CreateNodeTypeInput<TSchema>,
122
119
  ): NodeTypeDefinition<z.infer<TSchema>> {
123
120
  type TNode = z.infer<TSchema>;
124
121
 
@@ -152,10 +149,11 @@ export function createNodeType<TSchema extends ZodType>(
152
149
  typeGuard: createTypeGuard<TNode>(input.type),
153
150
 
154
151
  // Auto-generated default factory
155
- defaultFactory: (): TNode => ({
156
- type: input.type,
157
- ...input.defaultValues,
158
- } as TNode),
152
+ defaultFactory: (): TNode =>
153
+ ({
154
+ type: input.type,
155
+ ...input.defaultValues,
156
+ }) as TNode,
159
157
 
160
158
  treeDisplay: {
161
159
  icon: input.treeDisplay.icon,