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.
- package/.claude/settings.local.json +1 -3
- package/bin/cli.ts +66 -261
- package/build-astro.ts +150 -128
- package/dist/bin/cli.js +42 -185
- package/dist/bin/cli.js.map +2 -2
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
- package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
- package/dist/chunks/chunk-4ZRU52J2.js +169 -0
- package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
- package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
- package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
- package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
- package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
- package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
- package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
- package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
- package/dist/lib/client/index.js +1003 -475
- package/dist/lib/client/index.js.map +3 -3
- package/dist/lib/server/index.js +14393 -6371
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +342 -101
- package/dist/lib/shared/index.js.map +4 -4
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +64 -80
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +246 -186
- package/lib/client/ErrorBoundary.tsx +183 -132
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -3
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +663 -560
- package/lib/client/core/ComponentBuilder.ts +427 -155
- package/lib/client/core/ComponentRenderer.test.tsx +2 -4
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +242 -54
- package/lib/client/core/builders/linkBuilder.ts +72 -45
- package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
- package/lib/client/core/builders/listBuilder.ts +155 -89
- package/lib/client/core/builders/localeListBuilder.ts +97 -62
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +8 -9
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +2 -10
- package/lib/client/fontFamiliesService.ts +3 -3
- package/lib/client/hmr/HMRManager.tsx +47 -30
- package/lib/client/hmrCssReload.ts +49 -14
- package/lib/client/hmrWebSocket.ts +14 -19
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +23 -18
- package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
- package/lib/client/hooks/useVariables.ts +6 -4
- package/lib/client/hydration/HydrationUtils.test.ts +24 -25
- package/lib/client/hydration/HydrationUtils.ts +3 -4
- package/lib/client/i18nConfigService.test.ts +2 -7
- package/lib/client/i18nConfigService.ts +2 -2
- package/lib/client/meno-filter/MenoFilter.test.ts +47 -49
- package/lib/client/meno-filter/MenoFilter.ts +14 -15
- package/lib/client/meno-filter/bindings.ts +18 -43
- package/lib/client/meno-filter/init.ts +4 -4
- package/lib/client/meno-filter/renderer.ts +30 -32
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +4 -6
- package/lib/client/meno-filter/updates.ts +18 -23
- package/lib/client/meno-filter/utils.ts +1 -1
- package/lib/client/navigation.test.ts +174 -178
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
- package/lib/client/responsiveStyleResolver.test.ts +234 -232
- package/lib/client/responsiveStyleResolver.ts +74 -20
- package/lib/client/routing/RouteLoader.test.ts +24 -25
- package/lib/client/routing/RouteLoader.ts +27 -35
- package/lib/client/routing/Router.tsx +210 -153
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +18 -36
- package/lib/client/services/PrefetchService.test.ts +3 -3
- package/lib/client/services/PrefetchService.ts +23 -29
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +24 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +10 -7
- package/lib/client/styles/UtilityClassCollector.ts +62 -28
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -488
- package/lib/client/templateEngine.ts +203 -73
- package/lib/client/theme.test.ts +1 -1
- package/lib/client/theme.ts +0 -1
- package/lib/client/utils/toast.ts +0 -1
- package/lib/server/__integration__/api-routes.test.ts +8 -4
- package/lib/server/__integration__/cms-integration.test.ts +1 -4
- package/lib/server/__integration__/server-lifecycle.test.ts +4 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +3 -3
- package/lib/server/__integration__/test-helpers.ts +87 -74
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +26 -42
- package/lib/server/astro/componentEmitter.ts +35 -43
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1754 -34
- package/lib/server/astro/nodeToAstro.ts +232 -216
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
- package/lib/server/astro/pageEmitter.ts +9 -13
- package/lib/server/astro/tailwindMapper.test.ts +10 -37
- package/lib/server/astro/tailwindMapper.ts +33 -40
- package/lib/server/astro/templateTransformer.ts +17 -20
- package/lib/server/createServer.ts +7 -19
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +8 -19
- package/lib/server/fileWatcher.test.ts +164 -13
- package/lib/server/fileWatcher.ts +209 -124
- package/lib/server/index.ts +14 -17
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +39 -34
- package/lib/server/middleware/cors.test.ts +21 -21
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +7 -5
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +10 -8
- package/lib/server/middleware/logger.ts +17 -29
- package/lib/server/migrateTemplates.ts +3 -3
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +5 -4
- package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
- package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/colors.test.ts +2 -2
- package/lib/server/routes/api/components.ts +31 -35
- package/lib/server/routes/api/config.ts +3 -4
- package/lib/server/routes/api/core-routes.ts +49 -76
- package/lib/server/routes/api/enums.test.ts +2 -2
- package/lib/server/routes/api/functions.ts +9 -17
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +8 -11
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +12 -9
- package/lib/server/routes/api/variables.test.ts +3 -5
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +25 -28
- package/lib/server/routes/pages.ts +35 -31
- package/lib/server/routes/static.ts +17 -6
- package/lib/server/runtime/bundler.ts +98 -61
- package/lib/server/runtime/fs.ts +16 -26
- package/lib/server/runtime/httpServer.ts +8 -12
- package/lib/server/services/ColorService.test.ts +3 -3
- package/lib/server/services/ColorService.ts +37 -29
- package/lib/server/services/EnumService.test.ts +4 -8
- package/lib/server/services/EnumService.ts +11 -3
- package/lib/server/services/VariableService.test.ts +8 -12
- package/lib/server/services/VariableService.ts +11 -3
- package/lib/server/services/cmsService.test.ts +158 -120
- package/lib/server/services/cmsService.ts +36 -146
- package/lib/server/services/componentService.test.ts +125 -45
- package/lib/server/services/componentService.ts +70 -46
- package/lib/server/services/configService.test.ts +22 -45
- package/lib/server/services/configService.ts +50 -27
- package/lib/server/services/fileWatcherService.ts +42 -8
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +8 -10
- package/lib/server/services/pageService.ts +32 -18
- package/lib/server/ssr/attributeBuilder.ts +18 -8
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +1 -1
- package/lib/server/ssr/errorOverlay.ts +3 -9
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
- package/lib/server/ssr/htmlGenerator.test.ts +120 -44
- package/lib/server/ssr/htmlGenerator.ts +126 -91
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +27 -21
- package/lib/server/ssr/jsCollector.test.ts +8 -18
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
- package/lib/server/ssr/metaTagGenerator.ts +2 -2
- package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
- package/lib/server/ssr/ssrRenderer.test.ts +316 -256
- package/lib/server/ssr/ssrRenderer.ts +795 -243
- package/lib/server/ssrRenderer.test.ts +1048 -954
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +7 -7
- package/lib/server/validateStyleCoverage.ts +18 -21
- package/lib/server/websocketManager.ts +28 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.test.ts +5 -5
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQuery.test.ts +81 -0
- package/lib/shared/cmsQuery.ts +92 -0
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +60 -38
- package/lib/shared/colorConversions.ts +9 -9
- package/lib/shared/colorVariableUtils.test.ts +27 -5
- package/lib/shared/colorVariableUtils.ts +21 -12
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +8 -8
- package/lib/shared/cssGeneration.test.ts +285 -144
- package/lib/shared/cssGeneration.ts +217 -531
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +69 -70
- package/lib/shared/cssProperties.ts +298 -114
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +3 -3
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.test.ts +12 -12
- package/lib/shared/errorLogger.ts +2 -10
- package/lib/shared/errors.test.ts +2 -13
- package/lib/shared/errors.ts +2 -8
- package/lib/shared/expressionEvaluator.test.ts +145 -0
- package/lib/shared/expressionEvaluator.ts +52 -24
- package/lib/shared/fontLoader.test.ts +32 -18
- package/lib/shared/fontLoader.ts +2 -2
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +3 -7
- package/lib/shared/gradientUtils.ts +17 -14
- package/lib/shared/hrefRefs.test.ts +2 -2
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +4 -4
- package/lib/shared/i18n.ts +18 -38
- package/lib/shared/index.ts +27 -0
- package/lib/shared/inlineSvgStyleRules.ts +14 -13
- package/lib/shared/interactiveStyleMappings.test.ts +32 -54
- package/lib/shared/interactiveStyleMappings.ts +11 -24
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +11 -17
- package/lib/shared/itemTemplateUtils.ts +27 -39
- package/lib/shared/jsonRepair.ts +16 -10
- package/lib/shared/libraryLoader.test.ts +21 -55
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/linkUtils.ts +1 -1
- package/lib/shared/logger.test.ts +66 -0
- package/lib/shared/logger.ts +94 -0
- package/lib/shared/markdown.ts +25 -0
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +28 -16
- package/lib/shared/nodeUtils.ts +76 -23
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +2 -2
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -49
- package/lib/shared/paths/Path.test.ts +2 -2
- package/lib/shared/paths/Path.ts +0 -1
- package/lib/shared/paths/PathConverter.test.ts +1 -1
- package/lib/shared/paths/PathConverter.ts +17 -20
- package/lib/shared/paths/PathUtils.ts +13 -13
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +12 -10
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/permissions.test.ts +168 -0
- package/lib/shared/permissions.ts +162 -0
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +15 -26
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
- package/lib/shared/registry/ClientRegistry.ts +0 -2
- package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
- package/lib/shared/registry/ComponentRegistry.ts +12 -9
- package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -2
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/fieldPresets.ts +3 -1
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
- package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
- package/lib/shared/registry/nodeTypes/index.ts +26 -3
- package/lib/shared/responsiveScaling.test.ts +16 -34
- package/lib/shared/responsiveScaling.ts +61 -42
- package/lib/shared/responsiveStyleUtils.test.ts +0 -1
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
- package/lib/shared/richtext/htmlToTiptap.ts +2 -4
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +13 -13
- package/lib/shared/slugTranslator.ts +12 -16
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +18 -20
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -14
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +63 -145
- package/lib/shared/tree/PathBuilder.ts +59 -47
- package/lib/shared/treePathUtils.test.ts +51 -12
- package/lib/shared/treePathUtils.ts +91 -60
- package/lib/shared/types/api.ts +105 -8
- package/lib/shared/types/cms.test.ts +34 -0
- package/lib/shared/types/cms.ts +90 -34
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +51 -25
- package/lib/shared/types/errors.test.ts +1 -6
- package/lib/shared/types/errors.ts +3 -7
- package/lib/shared/types/experiments.ts +28 -28
- package/lib/shared/types/index.ts +25 -2
- package/lib/shared/types/permissions.ts +139 -0
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +51 -30
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +751 -321
- package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
- package/lib/shared/utilityClassMapper.test.ts +433 -95
- package/lib/shared/utilityClassMapper.ts +322 -249
- package/lib/shared/utilityClassNames.test.ts +38 -0
- package/lib/shared/utilityClassNames.ts +458 -0
- package/lib/shared/utils.test.ts +2 -10
- package/lib/shared/utils.ts +19 -10
- package/lib/shared/validation/cmsValidators.ts +2 -1
- package/lib/shared/validation/commentValidators.test.ts +53 -0
- package/lib/shared/validation/commentValidators.ts +12 -1
- package/lib/shared/validation/index.ts +1 -0
- package/lib/shared/validation/permissionsValidators.test.ts +49 -0
- package/lib/shared/validation/permissionsValidators.ts +49 -0
- package/lib/shared/validation/propValidator.test.ts +19 -21
- package/lib/shared/validation/propValidator.ts +13 -18
- package/lib/shared/validation/schemas.test.ts +64 -32
- package/lib/shared/validation/schemas.ts +616 -345
- package/lib/shared/validation/validators.test.ts +3 -8
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +24 -23
- package/lib/shared/viewportUnits.ts +12 -5
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
- package/lib/test-utils/factories/DomMockFactory.ts +17 -23
- package/lib/test-utils/factories/EventMockFactory.ts +7 -13
- package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
- package/lib/test-utils/factories/ServerMockFactory.ts +6 -10
- package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
- package/lib/test-utils/fixtures.ts +45 -45
- package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
- package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
- package/lib/test-utils/helpers.ts +1 -5
- package/lib/test-utils/index.ts +0 -4
- package/lib/test-utils/mockFactories.ts +13 -19
- package/lib/test-utils/mocks.ts +6 -4
- package/package.json +3 -5
- package/scripts/build-for-publish.mjs +2 -4
- package/scripts/build-meno-filter.ts +4 -7
- package/tsconfig.json +1 -0
- package/vite.config.ts +4 -4
- package/build-next.ts +0 -1361
- package/build-static.test.ts +0 -424
- package/build-static.ts +0 -1074
- package/dist/build-static.js +0 -36
- package/dist/chunks/chunk-2MHDV5BF.js +0 -251
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js +0 -559
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js +0 -322
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js +0 -467
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js +0 -6192
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
- package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
- package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
- package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
- package/dist/chunks/chunk-QB2LNO4W.js +0 -77
- package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
- package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
- package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
- package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
- package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
- package/dist/chunks/chunk-X754AHS5.js.map +0 -7
- package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
- package/dist/chunks/constants-STK2YBIW.js +0 -46
- package/dist/chunks/constants-STK2YBIW.js.map +0 -7
- package/dist/chunks/fs-JGINUXGL.js.map +0 -7
- package/dist/entries/server-router.js +0 -67
- package/dist/entries/server-router.js.map +0 -7
- package/entries/server-router.tsx +0 -81
- package/lib/server/providers/fileSystemPageProvider.ts +0 -160
- package/lib/server/webflow/buildWebflow.ts +0 -635
- package/lib/server/webflow/index.ts +0 -23
- package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
- package/lib/server/webflow/nodeToWebflow.ts +0 -2435
- package/lib/server/webflow/styleMapper.test.ts +0 -389
- package/lib/server/webflow/styleMapper.ts +0 -695
- package/lib/server/webflow/templateWrapper.ts +0 -49
- package/lib/server/webflow/types.ts +0 -396
- /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
|
@@ -23,7 +23,7 @@ export class HMRWebSocket {
|
|
|
23
23
|
private heartbeatInterval: ReturnType<typeof setInterval> | null = null;
|
|
24
24
|
private lastPongTime = 0;
|
|
25
25
|
private isIntentionallyClosed = false;
|
|
26
|
-
private messageQueue:
|
|
26
|
+
private messageQueue: unknown[] = [];
|
|
27
27
|
|
|
28
28
|
constructor(config: HMRWebSocketConfig) {
|
|
29
29
|
this.config = {
|
|
@@ -56,17 +56,15 @@ export class HMRWebSocket {
|
|
|
56
56
|
|
|
57
57
|
this.isIntentionallyClosed = false;
|
|
58
58
|
this.config.onStatusChange('connecting');
|
|
59
|
-
|
|
60
59
|
|
|
61
60
|
try {
|
|
62
61
|
this.ws = new WebSocket(this.config.url);
|
|
63
|
-
|
|
62
|
+
|
|
64
63
|
this.ws.onopen = () => this.handleOpen();
|
|
65
64
|
this.ws.onmessage = (event) => this.handleMessage(event);
|
|
66
65
|
this.ws.onerror = (error) => this.handleError(error);
|
|
67
66
|
this.ws.onclose = (event) => this.handleClose(event);
|
|
68
|
-
|
|
69
|
-
} catch (error) {
|
|
67
|
+
} catch (_error) {
|
|
70
68
|
this.scheduleReconnect();
|
|
71
69
|
}
|
|
72
70
|
}
|
|
@@ -74,10 +72,10 @@ export class HMRWebSocket {
|
|
|
74
72
|
private handleOpen(): void {
|
|
75
73
|
this.reconnectAttempts = 0;
|
|
76
74
|
this.config.onStatusChange('connected');
|
|
77
|
-
|
|
75
|
+
|
|
78
76
|
// Start heartbeat
|
|
79
77
|
this.startHeartbeat();
|
|
80
|
-
|
|
78
|
+
|
|
81
79
|
// Flush queued messages
|
|
82
80
|
this.flushMessageQueue();
|
|
83
81
|
}
|
|
@@ -97,14 +95,13 @@ export class HMRWebSocket {
|
|
|
97
95
|
}
|
|
98
96
|
}
|
|
99
97
|
|
|
100
|
-
private handleError(
|
|
98
|
+
private handleError(_error: Event): void {
|
|
101
99
|
this.config.onStatusChange('error');
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
private handleClose(
|
|
105
|
-
|
|
102
|
+
private handleClose(_event: CloseEvent): void {
|
|
106
103
|
this.stopHeartbeat();
|
|
107
|
-
|
|
104
|
+
|
|
108
105
|
if (!this.isIntentionallyClosed) {
|
|
109
106
|
this.config.onStatusChange('disconnected');
|
|
110
107
|
this.scheduleReconnect();
|
|
@@ -134,15 +131,14 @@ export class HMRWebSocket {
|
|
|
134
131
|
|
|
135
132
|
// Exponential backoff with jitter
|
|
136
133
|
const delay = Math.min(
|
|
137
|
-
this.config.initialReconnectDelay *
|
|
138
|
-
this.config.maxReconnectDelay
|
|
134
|
+
this.config.initialReconnectDelay * 2 ** this.reconnectAttempts,
|
|
135
|
+
this.config.maxReconnectDelay,
|
|
139
136
|
);
|
|
140
|
-
|
|
137
|
+
|
|
141
138
|
// Add jitter (±25%)
|
|
142
139
|
const jitter = delay * 0.25 * (Math.random() - 0.5);
|
|
143
140
|
const finalDelay = Math.max(delay + jitter, 100);
|
|
144
141
|
|
|
145
|
-
|
|
146
142
|
this.reconnectTimeout = setTimeout(() => {
|
|
147
143
|
this.reconnectAttempts++;
|
|
148
144
|
this.connect();
|
|
@@ -192,7 +188,7 @@ export class HMRWebSocket {
|
|
|
192
188
|
/**
|
|
193
189
|
* Send a message (queues if disconnected)
|
|
194
190
|
*/
|
|
195
|
-
send(data:
|
|
191
|
+
send(data: unknown): void {
|
|
196
192
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
197
193
|
this.ws.send(typeof data === 'string' ? data : JSON.stringify(data));
|
|
198
194
|
} else {
|
|
@@ -205,7 +201,7 @@ export class HMRWebSocket {
|
|
|
205
201
|
*/
|
|
206
202
|
getStatus(): 'connecting' | 'connected' | 'disconnected' | 'closed' {
|
|
207
203
|
if (!this.ws) return 'disconnected';
|
|
208
|
-
|
|
204
|
+
|
|
209
205
|
switch (this.ws.readyState) {
|
|
210
206
|
case WebSocket.CONNECTING:
|
|
211
207
|
return 'connecting';
|
|
@@ -225,7 +221,7 @@ export class HMRWebSocket {
|
|
|
225
221
|
close(): void {
|
|
226
222
|
this.isIntentionallyClosed = true;
|
|
227
223
|
this.stopHeartbeat();
|
|
228
|
-
|
|
224
|
+
|
|
229
225
|
if (this.reconnectTimeout) {
|
|
230
226
|
clearTimeout(this.reconnectTimeout);
|
|
231
227
|
this.reconnectTimeout = null;
|
|
@@ -266,4 +262,3 @@ export class HMRWebSocket {
|
|
|
266
262
|
this.config.onStatusChange = handler;
|
|
267
263
|
}
|
|
268
264
|
}
|
|
269
|
-
|
|
@@ -12,10 +12,10 @@ describe('useColorVariables utilities', () => {
|
|
|
12
12
|
test('returns all color variables when input is empty', () => {
|
|
13
13
|
const colors: ColorVariables = {
|
|
14
14
|
colors: {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
15
|
+
primary: '#007acc',
|
|
16
|
+
secondary: '#6b7280',
|
|
17
|
+
background: '#ffffff',
|
|
18
|
+
},
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const result = getColorVariableSuggestions(colors, '');
|
|
@@ -28,11 +28,11 @@ describe('useColorVariables utilities', () => {
|
|
|
28
28
|
test('filters color variables by input', () => {
|
|
29
29
|
const colors: ColorVariables = {
|
|
30
30
|
colors: {
|
|
31
|
-
|
|
31
|
+
primary: '#007acc',
|
|
32
32
|
'primary-light': '#0098ff',
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
33
|
+
secondary: '#6b7280',
|
|
34
|
+
background: '#ffffff',
|
|
35
|
+
},
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
const result = getColorVariableSuggestions(colors, 'primary');
|
|
@@ -44,9 +44,9 @@ describe('useColorVariables utilities', () => {
|
|
|
44
44
|
test('is case insensitive', () => {
|
|
45
45
|
const colors: ColorVariables = {
|
|
46
46
|
colors: {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
47
|
+
Primary: '#007acc',
|
|
48
|
+
SECONDARY: '#6b7280',
|
|
49
|
+
},
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
const result = getColorVariableSuggestions(colors, 'primary');
|
|
@@ -57,9 +57,9 @@ describe('useColorVariables utilities', () => {
|
|
|
57
57
|
test('handles whitespace in input', () => {
|
|
58
58
|
const colors: ColorVariables = {
|
|
59
59
|
colors: {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
60
|
+
primary: '#007acc',
|
|
61
|
+
secondary: '#6b7280',
|
|
62
|
+
},
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
const result = getColorVariableSuggestions(colors, ' primary ');
|
|
@@ -72,8 +72,8 @@ describe('useColorVariables utilities', () => {
|
|
|
72
72
|
colors: {
|
|
73
73
|
'text-primary': '#000000',
|
|
74
74
|
'text-secondary': '#6b7280',
|
|
75
|
-
|
|
76
|
-
}
|
|
75
|
+
background: '#ffffff',
|
|
76
|
+
},
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
const result = getColorVariableSuggestions(colors, 'text');
|
|
@@ -85,8 +85,8 @@ describe('useColorVariables utilities', () => {
|
|
|
85
85
|
test('formats variables correctly', () => {
|
|
86
86
|
const colors: ColorVariables = {
|
|
87
87
|
colors: {
|
|
88
|
-
'my-color': '#ff0000'
|
|
89
|
-
}
|
|
88
|
+
'my-color': '#ff0000',
|
|
89
|
+
},
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
const result = getColorVariableSuggestions(colors, 'my');
|
|
@@ -96,9 +96,9 @@ describe('useColorVariables utilities', () => {
|
|
|
96
96
|
test('returns empty array when no matches', () => {
|
|
97
97
|
const colors: ColorVariables = {
|
|
98
98
|
colors: {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
99
|
+
primary: '#007acc',
|
|
100
|
+
secondary: '#6b7280',
|
|
101
|
+
},
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
const result = getColorVariableSuggestions(colors, 'nonexistent');
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { useState, useEffect, useRef } from 'react';
|
|
6
|
-
import type { ColorVariables, ThemeEntry
|
|
6
|
+
import type { ColorVariables, ThemeEntry } from '../../shared/types';
|
|
7
7
|
import { applyNonce } from '../styles/cspNonce';
|
|
8
8
|
|
|
9
9
|
let cachedColors: Record<string, ColorVariables> = {};
|
|
10
10
|
let cachedThemes: ThemeEntry[] | null = null;
|
|
11
11
|
let cachedDefaultTheme: string | null = null;
|
|
12
|
-
|
|
12
|
+
const hmrCallbacks: Set<() => void> = new Set();
|
|
13
13
|
|
|
14
14
|
// Setup HMR listener immediately when module loads
|
|
15
15
|
function initializeHMRListener() {
|
|
@@ -30,7 +30,9 @@ function initializeHMRListener() {
|
|
|
30
30
|
await injectUpdatedThemeCSS();
|
|
31
31
|
|
|
32
32
|
// Notify all listeners to refresh their data
|
|
33
|
-
hmrCallbacks.forEach(callback =>
|
|
33
|
+
hmrCallbacks.forEach((callback) => {
|
|
34
|
+
callback();
|
|
35
|
+
});
|
|
34
36
|
});
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -48,10 +50,10 @@ async function injectUpdatedThemeCSS() {
|
|
|
48
50
|
const response = await fetch('/api/themes');
|
|
49
51
|
if (!response.ok) return;
|
|
50
52
|
|
|
51
|
-
const data = await response.json() as { themes: Array<{ name: string; label: string }>; default: string };
|
|
53
|
+
const data = (await response.json()) as { themes: Array<{ name: string; label: string }>; default: string };
|
|
52
54
|
|
|
53
55
|
// Fetch all theme colors
|
|
54
|
-
const themeColors: Record<string,
|
|
56
|
+
const themeColors: Record<string, Record<string, string>> = {};
|
|
55
57
|
for (const theme of data.themes) {
|
|
56
58
|
const colorResponse = await fetch(`/api/colors?theme=${encodeURIComponent(theme.name)}`);
|
|
57
59
|
if (colorResponse.ok) {
|
|
@@ -62,15 +64,15 @@ async function injectUpdatedThemeCSS() {
|
|
|
62
64
|
// Also get default theme colors
|
|
63
65
|
const defaultResponse = await fetch('/api/colors');
|
|
64
66
|
if (defaultResponse.ok) {
|
|
65
|
-
themeColors
|
|
67
|
+
themeColors.default = (await defaultResponse.json()).colors;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
// Generate CSS
|
|
69
71
|
let css = '';
|
|
70
72
|
|
|
71
73
|
// Default theme in :root
|
|
72
|
-
if (themeColors
|
|
73
|
-
const vars = Object.entries(themeColors
|
|
74
|
+
if (themeColors.default) {
|
|
75
|
+
const vars = Object.entries(themeColors.default)
|
|
74
76
|
.map(([name, value]) => ` --${name}: ${value};`)
|
|
75
77
|
.join('\n');
|
|
76
78
|
css += `:root {\n${vars}\n}\n\n`;
|
|
@@ -78,8 +80,9 @@ async function injectUpdatedThemeCSS() {
|
|
|
78
80
|
|
|
79
81
|
// Each theme in [theme="..."]
|
|
80
82
|
for (const theme of data.themes) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
const themeVars = themeColors[theme.name];
|
|
84
|
+
if (themeVars) {
|
|
85
|
+
const vars = Object.entries(themeVars)
|
|
83
86
|
.map(([name, value]) => ` --${name}: ${value};`)
|
|
84
87
|
.join('\n');
|
|
85
88
|
css += `[theme="${theme.name}"] {\n${vars}\n}\n\n`;
|
|
@@ -94,7 +97,7 @@ async function injectUpdatedThemeCSS() {
|
|
|
94
97
|
applyNonce(themeStyleTag);
|
|
95
98
|
// Insert after the main style tag
|
|
96
99
|
const mainStyle = document.querySelector('style');
|
|
97
|
-
if (mainStyle
|
|
100
|
+
if (mainStyle?.nextSibling) {
|
|
98
101
|
document.head.insertBefore(themeStyleTag, mainStyle.nextSibling);
|
|
99
102
|
} else {
|
|
100
103
|
document.head.appendChild(themeStyleTag);
|
|
@@ -109,7 +112,9 @@ async function injectUpdatedThemeCSS() {
|
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
export function useColorVariables(themeName?: string) {
|
|
112
|
-
const [colors, setColors] = useState<ColorVariables | null>(
|
|
115
|
+
const [colors, setColors] = useState<ColorVariables | null>(
|
|
116
|
+
themeName && cachedColors[themeName] ? cachedColors[themeName] : null,
|
|
117
|
+
);
|
|
113
118
|
const [loading, setLoading] = useState(!cachedColors[themeName || 'default']);
|
|
114
119
|
const [error, setError] = useState<Error | null>(null);
|
|
115
120
|
const callbackRef = useRef<(() => void) | null>(null);
|
|
@@ -125,7 +130,7 @@ export function useColorVariables(themeName?: string) {
|
|
|
125
130
|
if (!response.ok) {
|
|
126
131
|
throw new Error('Failed to fetch colors');
|
|
127
132
|
}
|
|
128
|
-
const data = await response.json() as ColorVariables;
|
|
133
|
+
const data = (await response.json()) as ColorVariables;
|
|
129
134
|
cachedColors[theme] = data;
|
|
130
135
|
setColors(data);
|
|
131
136
|
setError(null);
|
|
@@ -157,7 +162,7 @@ export function useColorVariables(themeName?: string) {
|
|
|
157
162
|
if (!response.ok) {
|
|
158
163
|
throw new Error('Failed to fetch colors');
|
|
159
164
|
}
|
|
160
|
-
const data = await response.json() as ColorVariables;
|
|
165
|
+
const data = (await response.json()) as ColorVariables;
|
|
161
166
|
cachedColors[theme] = data;
|
|
162
167
|
setColors(data);
|
|
163
168
|
setError(null);
|
|
@@ -206,7 +211,7 @@ export function useThemes() {
|
|
|
206
211
|
if (!response.ok) {
|
|
207
212
|
throw new Error('Failed to fetch themes');
|
|
208
213
|
}
|
|
209
|
-
const data = await response.json() as { themes: ThemeEntry[]; default: string };
|
|
214
|
+
const data = (await response.json()) as { themes: ThemeEntry[]; default: string };
|
|
210
215
|
cachedThemes = data.themes;
|
|
211
216
|
cachedDefaultTheme = data.default;
|
|
212
217
|
setThemes(data.themes);
|
|
@@ -234,13 +239,13 @@ export function getColorVariableSuggestions(colors: ColorVariables | null, input
|
|
|
234
239
|
|
|
235
240
|
const normalizedInput = input.trim().toLowerCase();
|
|
236
241
|
if (!normalizedInput) {
|
|
237
|
-
return Object.keys(colors.colors).map(name => `var(--${name})`);
|
|
242
|
+
return Object.keys(colors.colors).map((name) => `var(--${name})`);
|
|
238
243
|
}
|
|
239
244
|
|
|
240
245
|
// Filter color variable names that match the input
|
|
241
246
|
return Object.keys(colors.colors)
|
|
242
|
-
.filter(name => name.toLowerCase().includes(normalizedInput) || normalizedInput.includes(name.toLowerCase()))
|
|
243
|
-
.map(name => `var(--${name})`);
|
|
247
|
+
.filter((name) => name.toLowerCase().includes(normalizedInput) || normalizedInput.includes(name.toLowerCase()))
|
|
248
|
+
.map((name) => `var(--${name})`);
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Handles property input, suggestions, and keyboard navigation
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useState, useRef
|
|
6
|
+
import { useState, useRef } from 'react';
|
|
7
7
|
import { filterCSSProperties } from '../../shared/cssProperties';
|
|
8
8
|
|
|
9
9
|
export function usePropertyAutocomplete(initialProperty: string = '') {
|
|
@@ -17,12 +17,10 @@ export function usePropertyAutocomplete(initialProperty: string = '') {
|
|
|
17
17
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
18
18
|
if (e.key === 'ArrowDown') {
|
|
19
19
|
e.preventDefault();
|
|
20
|
-
setSelectedIndex(prev =>
|
|
21
|
-
prev < suggestions.length - 1 ? prev + 1 : prev
|
|
22
|
-
);
|
|
20
|
+
setSelectedIndex((prev) => (prev < suggestions.length - 1 ? prev + 1 : prev));
|
|
23
21
|
} else if (e.key === 'ArrowUp') {
|
|
24
22
|
e.preventDefault();
|
|
25
|
-
setSelectedIndex(prev => prev > 0 ? prev - 1 : -1);
|
|
23
|
+
setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1));
|
|
26
24
|
}
|
|
27
25
|
};
|
|
28
26
|
|
|
@@ -35,6 +33,6 @@ export function usePropertyAutocomplete(initialProperty: string = '') {
|
|
|
35
33
|
setSelectedIndex,
|
|
36
34
|
suggestions,
|
|
37
35
|
inputRef,
|
|
38
|
-
handleKeyDown
|
|
36
|
+
handleKeyDown,
|
|
39
37
|
};
|
|
40
38
|
}
|
|
@@ -6,7 +6,7 @@ import { useState, useEffect, useRef } from 'react';
|
|
|
6
6
|
import type { CSSVariable } from '../../shared/types/variables';
|
|
7
7
|
|
|
8
8
|
let cachedVariables: CSSVariable[] | null = null;
|
|
9
|
-
|
|
9
|
+
const hmrCallbacks: Set<() => void> = new Set();
|
|
10
10
|
|
|
11
11
|
// Setup HMR listener immediately when module loads
|
|
12
12
|
function initializeHMRListener() {
|
|
@@ -22,7 +22,9 @@ function initializeHMRListener() {
|
|
|
22
22
|
cachedVariables = null;
|
|
23
23
|
|
|
24
24
|
// Notify all listeners to refresh their data
|
|
25
|
-
hmrCallbacks.forEach(callback =>
|
|
25
|
+
hmrCallbacks.forEach((callback) => {
|
|
26
|
+
callback();
|
|
27
|
+
});
|
|
26
28
|
});
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -45,7 +47,7 @@ export function useVariables() {
|
|
|
45
47
|
if (!response.ok) {
|
|
46
48
|
throw new Error('Failed to fetch variables');
|
|
47
49
|
}
|
|
48
|
-
const data = await response.json() as { status: string; config: { variables: CSSVariable[] } };
|
|
50
|
+
const data = (await response.json()) as { status: string; config: { variables: CSSVariable[] } };
|
|
49
51
|
cachedVariables = data.config.variables;
|
|
50
52
|
setVariables(cachedVariables);
|
|
51
53
|
setError(null);
|
|
@@ -76,7 +78,7 @@ export function useVariables() {
|
|
|
76
78
|
if (!response.ok) {
|
|
77
79
|
throw new Error('Failed to fetch variables');
|
|
78
80
|
}
|
|
79
|
-
const data = await response.json() as { status: string; config: { variables: CSSVariable[] } };
|
|
81
|
+
const data = (await response.json()) as { status: string; config: { variables: CSSVariable[] } };
|
|
80
82
|
cachedVariables = data.config.variables;
|
|
81
83
|
setVariables(cachedVariables);
|
|
82
84
|
setError(null);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { test, expect, describe, beforeEach, afterEach, mock } from
|
|
2
|
-
import { detectSSRContent, getInitialLoadingState } from
|
|
1
|
+
import { test, expect, describe, beforeEach, afterEach, mock } from 'bun:test';
|
|
2
|
+
import { detectSSRContent, getInitialLoadingState } from './HydrationUtils';
|
|
3
3
|
|
|
4
|
-
describe(
|
|
4
|
+
describe('HydrationUtils', () => {
|
|
5
5
|
let originalDocument: Document | undefined;
|
|
6
6
|
let originalWindow: (Window & typeof globalThis) | undefined;
|
|
7
7
|
let mockGetElementById: ReturnType<typeof mock>;
|
|
@@ -22,11 +22,11 @@ describe("HydrationUtils", () => {
|
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
describe(
|
|
26
|
-
test(
|
|
25
|
+
describe('detectSSRContent', () => {
|
|
26
|
+
test('should return true when root element exists with children', () => {
|
|
27
27
|
// Create a mock root element with children
|
|
28
28
|
const mockRoot = {
|
|
29
|
-
id:
|
|
29
|
+
id: 'root',
|
|
30
30
|
children: {
|
|
31
31
|
length: 1,
|
|
32
32
|
},
|
|
@@ -40,13 +40,13 @@ describe("HydrationUtils", () => {
|
|
|
40
40
|
|
|
41
41
|
const result = detectSSRContent();
|
|
42
42
|
expect(result).toBe(true);
|
|
43
|
-
expect(mockGetElementById).toHaveBeenCalledWith(
|
|
43
|
+
expect(mockGetElementById).toHaveBeenCalledWith('root');
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
test(
|
|
46
|
+
test('should return false when root element exists without children', () => {
|
|
47
47
|
// Create a mock root element without children
|
|
48
48
|
const mockRoot = {
|
|
49
|
-
id:
|
|
49
|
+
id: 'root',
|
|
50
50
|
children: {
|
|
51
51
|
length: 0,
|
|
52
52
|
},
|
|
@@ -60,10 +60,10 @@ describe("HydrationUtils", () => {
|
|
|
60
60
|
|
|
61
61
|
const result = detectSSRContent();
|
|
62
62
|
expect(result).toBe(false);
|
|
63
|
-
expect(mockGetElementById).toHaveBeenCalledWith(
|
|
63
|
+
expect(mockGetElementById).toHaveBeenCalledWith('root');
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
test(
|
|
66
|
+
test('should return false when root element does not exist', () => {
|
|
67
67
|
// Mock getElementById to return null
|
|
68
68
|
mockGetElementById = mock(() => null);
|
|
69
69
|
global.window = {} as any;
|
|
@@ -73,14 +73,14 @@ describe("HydrationUtils", () => {
|
|
|
73
73
|
|
|
74
74
|
const result = detectSSRContent();
|
|
75
75
|
expect(result).toBe(false);
|
|
76
|
-
expect(mockGetElementById).toHaveBeenCalledWith(
|
|
76
|
+
expect(mockGetElementById).toHaveBeenCalledWith('root');
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
test(
|
|
79
|
+
test('should return false when window is undefined (SSR environment)', () => {
|
|
80
80
|
// Mock SSR environment
|
|
81
81
|
const originalWindow = globalThis.window;
|
|
82
82
|
const originalDocument = globalThis.document;
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
// @ts-expect-error - intentionally removing window for SSR test
|
|
85
85
|
delete globalThis.window;
|
|
86
86
|
// @ts-expect-error - intentionally removing document for SSR test
|
|
@@ -94,10 +94,10 @@ describe("HydrationUtils", () => {
|
|
|
94
94
|
globalThis.document = originalDocument;
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
test(
|
|
97
|
+
test('should return false when document is undefined', () => {
|
|
98
98
|
// Mock environment without document
|
|
99
99
|
const originalDocument = globalThis.document;
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
// @ts-expect-error - intentionally removing document for test
|
|
102
102
|
delete globalThis.document;
|
|
103
103
|
|
|
@@ -108,10 +108,10 @@ describe("HydrationUtils", () => {
|
|
|
108
108
|
globalThis.document = originalDocument;
|
|
109
109
|
});
|
|
110
110
|
|
|
111
|
-
test(
|
|
111
|
+
test('should handle root element with multiple children', () => {
|
|
112
112
|
// Create a mock root element with multiple children
|
|
113
113
|
const mockRoot = {
|
|
114
|
-
id:
|
|
114
|
+
id: 'root',
|
|
115
115
|
children: {
|
|
116
116
|
length: 3,
|
|
117
117
|
},
|
|
@@ -125,30 +125,29 @@ describe("HydrationUtils", () => {
|
|
|
125
125
|
|
|
126
126
|
const result = detectSSRContent();
|
|
127
127
|
expect(result).toBe(true);
|
|
128
|
-
expect(mockGetElementById).toHaveBeenCalledWith(
|
|
128
|
+
expect(mockGetElementById).toHaveBeenCalledWith('root');
|
|
129
129
|
});
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
describe(
|
|
133
|
-
test(
|
|
132
|
+
describe('getInitialLoadingState', () => {
|
|
133
|
+
test('should return false when SSR content exists (smooth hydration)', () => {
|
|
134
134
|
const result = getInitialLoadingState(true);
|
|
135
135
|
expect(result).toBe(false);
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
test(
|
|
138
|
+
test('should return true when no SSR content exists (show loading)', () => {
|
|
139
139
|
const result = getInitialLoadingState(false);
|
|
140
140
|
expect(result).toBe(true);
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
test(
|
|
143
|
+
test('should handle edge case with explicit false', () => {
|
|
144
144
|
const result = getInitialLoadingState(false);
|
|
145
145
|
expect(result).toBe(true);
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
test(
|
|
148
|
+
test('should handle edge case with explicit true', () => {
|
|
149
149
|
const result = getInitialLoadingState(true);
|
|
150
150
|
expect(result).toBe(false);
|
|
151
151
|
});
|
|
152
152
|
});
|
|
153
153
|
});
|
|
154
|
-
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* Detects if server-side rendered content exists in the DOM.
|
|
8
8
|
* Checks if the root element has children, which indicates SSR rendered content.
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* @returns true if SSR content is detected, false otherwise
|
|
11
11
|
*/
|
|
12
12
|
export function detectSSRContent(): boolean {
|
|
@@ -16,14 +16,14 @@ export function detectSSRContent(): boolean {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const rootElement = document.getElementById('root');
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
// SSR content exists if root element has children
|
|
21
21
|
return rootElement !== null && rootElement.children.length > 0;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Determines the initial loading state based on SSR content presence.
|
|
26
|
-
*
|
|
26
|
+
*
|
|
27
27
|
* @param hasSSRContent - Whether SSR content was detected
|
|
28
28
|
* @returns false if SSR content exists (for smooth hydration), true otherwise
|
|
29
29
|
*/
|
|
@@ -32,4 +32,3 @@ export function getInitialLoadingState(hasSSRContent: boolean): boolean {
|
|
|
32
32
|
// If no SSR content, start with loading=true to show loading state
|
|
33
33
|
return !hasSSRContent;
|
|
34
34
|
}
|
|
35
|
-
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect, beforeEach } from 'bun:test';
|
|
2
|
-
import {
|
|
3
|
-
getI18nConfig,
|
|
4
|
-
isI18nConfigLoaded,
|
|
5
|
-
invalidateI18nConfig,
|
|
6
|
-
setI18nConfig,
|
|
7
|
-
} from './i18nConfigService';
|
|
2
|
+
import { getI18nConfig, isI18nConfigLoaded, invalidateI18nConfig, setI18nConfig } from './i18nConfigService';
|
|
8
3
|
import { DEFAULT_I18N_CONFIG } from '../shared/i18n';
|
|
9
4
|
|
|
10
5
|
describe('i18nConfigService', () => {
|
|
@@ -51,7 +46,7 @@ describe('i18nConfigService', () => {
|
|
|
51
46
|
test('sets config that can be retrieved', () => {
|
|
52
47
|
const customConfig = {
|
|
53
48
|
defaultLocale: 'de',
|
|
54
|
-
locales: [{ code: 'de', name: 'German', nativeName: 'Deutsch', langTag: 'de-DE' }]
|
|
49
|
+
locales: [{ code: 'de', name: 'German', nativeName: 'Deutsch', langTag: 'de-DE' }],
|
|
55
50
|
};
|
|
56
51
|
setI18nConfig(customConfig);
|
|
57
52
|
const config = getI18nConfig();
|
|
@@ -26,13 +26,13 @@ export async function fetchI18nConfig(): Promise<I18nConfig> {
|
|
|
26
26
|
|
|
27
27
|
// Create new request
|
|
28
28
|
configPromise = fetch('/api/config')
|
|
29
|
-
.then(response => {
|
|
29
|
+
.then((response) => {
|
|
30
30
|
if (!response.ok) {
|
|
31
31
|
throw new Error('Failed to fetch config');
|
|
32
32
|
}
|
|
33
33
|
return response.json();
|
|
34
34
|
})
|
|
35
|
-
.then(config => {
|
|
35
|
+
.then((config) => {
|
|
36
36
|
cachedConfig = migrateI18nConfig(config.i18n);
|
|
37
37
|
return cachedConfig;
|
|
38
38
|
})
|