@useavalon/avalon 0.1.13 → 0.1.15

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 (230) hide show
  1. package/dist/mod.js +1 -0
  2. package/dist/src/build/integration-bundler-plugin.js +1 -0
  3. package/dist/src/build/integration-config.js +1 -0
  4. package/dist/src/build/integration-detection-plugin.js +1 -0
  5. package/dist/src/build/integration-resolver-plugin.js +1 -0
  6. package/dist/src/build/island-manifest.js +1 -0
  7. package/dist/src/build/island-types-generator.js +5 -0
  8. package/dist/src/build/mdx-island-transform.js +2 -0
  9. package/dist/src/build/mdx-plugin.js +1 -0
  10. package/dist/src/build/page-island-transform.js +3 -0
  11. package/dist/src/build/prop-extractors/index.js +1 -0
  12. package/dist/src/build/prop-extractors/lit.js +1 -0
  13. package/dist/src/build/prop-extractors/qwik.js +1 -0
  14. package/dist/src/build/prop-extractors/solid.js +1 -0
  15. package/dist/src/build/prop-extractors/svelte.js +1 -0
  16. package/dist/src/build/prop-extractors/vue.js +1 -0
  17. package/dist/src/build/sidecar-file-manager.js +1 -0
  18. package/dist/src/build/sidecar-renderer.js +6 -0
  19. package/dist/src/client/adapters/index.js +1 -0
  20. package/dist/src/client/components.js +1 -0
  21. package/dist/src/client/css-hmr-handler.js +1 -0
  22. package/dist/src/client/framework-adapter.js +13 -0
  23. package/dist/src/client/hmr-coordinator.js +1 -0
  24. package/dist/src/client/hmr-error-overlay.js +214 -0
  25. package/dist/src/client/main.js +39 -0
  26. package/dist/src/components/Image.js +1 -0
  27. package/dist/src/components/IslandErrorBoundary.js +1 -0
  28. package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
  29. package/dist/src/components/LayoutErrorBoundary.js +1 -0
  30. package/dist/src/components/PersistentIsland.js +1 -0
  31. package/dist/src/components/StreamingErrorBoundary.js +1 -0
  32. package/dist/src/components/StreamingLayout.js +29 -0
  33. package/dist/src/core/components/component-analyzer.js +1 -0
  34. package/dist/src/core/components/component-detection.js +5 -0
  35. package/dist/src/core/components/enhanced-framework-detector.js +1 -0
  36. package/dist/src/core/components/framework-registry.js +1 -0
  37. package/dist/src/core/content/mdx-processor.js +1 -0
  38. package/dist/src/core/integrations/index.js +1 -0
  39. package/dist/src/core/integrations/loader.js +1 -0
  40. package/dist/src/core/integrations/registry.js +1 -0
  41. package/dist/src/core/islands/island-persistence.js +1 -0
  42. package/dist/src/core/islands/island-state-serializer.js +1 -0
  43. package/dist/src/core/islands/persistent-island-context.js +1 -0
  44. package/dist/src/core/islands/use-persistent-state.js +1 -0
  45. package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
  46. package/dist/src/core/layout/layout-cache-manager.js +1 -0
  47. package/dist/src/core/layout/layout-composer.js +1 -0
  48. package/dist/src/core/layout/layout-data-loader.js +1 -0
  49. package/dist/src/core/layout/layout-discovery.js +1 -0
  50. package/dist/src/core/layout/layout-matcher.js +1 -0
  51. package/dist/src/core/layout/layout-types.js +1 -0
  52. package/dist/src/core/modules/framework-module-resolver.js +1 -0
  53. package/dist/src/islands/component-analysis.js +1 -0
  54. package/dist/src/islands/css-utils.js +17 -0
  55. package/dist/src/islands/discovery/index.js +1 -0
  56. package/dist/src/islands/discovery/registry.js +1 -0
  57. package/dist/src/islands/discovery/resolver.js +2 -0
  58. package/dist/src/islands/discovery/scanner.js +1 -0
  59. package/dist/src/islands/discovery/types.js +1 -0
  60. package/dist/src/islands/discovery/validator.js +18 -0
  61. package/dist/src/islands/discovery/watcher.js +1 -0
  62. package/dist/src/islands/framework-detection.js +1 -0
  63. package/dist/src/islands/integration-loader.js +1 -0
  64. package/dist/src/islands/island.js +1 -0
  65. package/dist/src/islands/render-cache.js +1 -0
  66. package/dist/src/islands/types.js +1 -0
  67. package/dist/src/islands/universal-css-collector.js +5 -0
  68. package/dist/src/islands/universal-head-collector.js +2 -0
  69. package/dist/src/layout-system.js +1 -0
  70. package/dist/src/middleware/discovery.js +1 -0
  71. package/dist/src/middleware/executor.js +1 -0
  72. package/dist/src/middleware/index.js +1 -0
  73. package/dist/src/middleware/types.js +1 -0
  74. package/dist/src/nitro/build-config.js +1 -0
  75. package/dist/src/nitro/config.js +1 -0
  76. package/dist/src/nitro/error-handler.js +198 -0
  77. package/dist/src/nitro/index.js +1 -0
  78. package/dist/src/nitro/island-manifest.js +2 -0
  79. package/dist/src/nitro/middleware-adapter.js +1 -0
  80. package/dist/src/nitro/renderer.js +183 -0
  81. package/dist/src/nitro/route-discovery.js +1 -0
  82. package/dist/src/nitro/types.js +1 -0
  83. package/dist/src/render/collect-css.js +3 -0
  84. package/dist/src/render/error-pages.js +48 -0
  85. package/dist/src/render/isolated-ssr-renderer.js +1 -0
  86. package/dist/src/render/ssr.js +90 -0
  87. package/dist/src/schemas/api.js +1 -0
  88. package/dist/src/schemas/core.js +1 -0
  89. package/dist/src/schemas/index.js +1 -0
  90. package/dist/src/schemas/layout.js +1 -0
  91. package/dist/src/schemas/routing/index.js +1 -0
  92. package/dist/src/schemas/routing.js +1 -0
  93. package/dist/src/types/as-island.js +1 -0
  94. package/dist/src/types/layout.js +1 -0
  95. package/dist/src/types/routing.js +1 -0
  96. package/dist/src/types/types.js +1 -0
  97. package/dist/src/utils/dev-logger.js +12 -0
  98. package/dist/src/utils/fs.js +1 -0
  99. package/dist/src/vite-plugin/auto-discover.js +1 -0
  100. package/dist/src/vite-plugin/config.js +1 -0
  101. package/dist/src/vite-plugin/errors.js +1 -0
  102. package/dist/src/vite-plugin/image-optimization.js +45 -0
  103. package/dist/src/vite-plugin/integration-activator.js +1 -0
  104. package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
  105. package/dist/src/vite-plugin/module-discovery.js +1 -0
  106. package/dist/src/vite-plugin/nitro-integration.js +42 -0
  107. package/dist/src/vite-plugin/plugin.js +1 -0
  108. package/dist/src/vite-plugin/types.js +1 -0
  109. package/dist/src/vite-plugin/validation.js +2 -0
  110. package/package.json +14 -20
  111. package/mod.ts +0 -302
  112. package/src/build/integration-bundler-plugin.ts +0 -116
  113. package/src/build/integration-config.ts +0 -168
  114. package/src/build/integration-detection-plugin.ts +0 -117
  115. package/src/build/integration-resolver-plugin.ts +0 -90
  116. package/src/build/island-manifest.ts +0 -269
  117. package/src/build/island-types-generator.ts +0 -476
  118. package/src/build/mdx-island-transform.ts +0 -464
  119. package/src/build/mdx-plugin.ts +0 -98
  120. package/src/build/page-island-transform.ts +0 -598
  121. package/src/build/prop-extractors/index.ts +0 -21
  122. package/src/build/prop-extractors/lit.ts +0 -140
  123. package/src/build/prop-extractors/qwik.ts +0 -16
  124. package/src/build/prop-extractors/solid.ts +0 -125
  125. package/src/build/prop-extractors/svelte.ts +0 -194
  126. package/src/build/prop-extractors/vue.ts +0 -111
  127. package/src/build/sidecar-file-manager.ts +0 -104
  128. package/src/build/sidecar-renderer.ts +0 -30
  129. package/src/client/adapters/index.ts +0 -21
  130. package/src/client/components.ts +0 -35
  131. package/src/client/css-hmr-handler.ts +0 -344
  132. package/src/client/framework-adapter.ts +0 -462
  133. package/src/client/hmr-coordinator.ts +0 -396
  134. package/src/client/hmr-error-overlay.js +0 -533
  135. package/src/client/main.js +0 -824
  136. package/src/components/Image.tsx +0 -123
  137. package/src/components/IslandErrorBoundary.tsx +0 -145
  138. package/src/components/LayoutDataErrorBoundary.tsx +0 -141
  139. package/src/components/LayoutErrorBoundary.tsx +0 -127
  140. package/src/components/PersistentIsland.tsx +0 -52
  141. package/src/components/StreamingErrorBoundary.tsx +0 -233
  142. package/src/components/StreamingLayout.tsx +0 -538
  143. package/src/core/components/component-analyzer.ts +0 -192
  144. package/src/core/components/component-detection.ts +0 -508
  145. package/src/core/components/enhanced-framework-detector.ts +0 -500
  146. package/src/core/components/framework-registry.ts +0 -563
  147. package/src/core/content/mdx-processor.ts +0 -46
  148. package/src/core/integrations/index.ts +0 -19
  149. package/src/core/integrations/loader.ts +0 -125
  150. package/src/core/integrations/registry.ts +0 -175
  151. package/src/core/islands/island-persistence.ts +0 -325
  152. package/src/core/islands/island-state-serializer.ts +0 -258
  153. package/src/core/islands/persistent-island-context.tsx +0 -80
  154. package/src/core/islands/use-persistent-state.ts +0 -68
  155. package/src/core/layout/enhanced-layout-resolver.ts +0 -322
  156. package/src/core/layout/layout-cache-manager.ts +0 -485
  157. package/src/core/layout/layout-composer.ts +0 -357
  158. package/src/core/layout/layout-data-loader.ts +0 -516
  159. package/src/core/layout/layout-discovery.ts +0 -243
  160. package/src/core/layout/layout-matcher.ts +0 -299
  161. package/src/core/layout/layout-types.ts +0 -110
  162. package/src/core/modules/framework-module-resolver.ts +0 -273
  163. package/src/islands/component-analysis.ts +0 -213
  164. package/src/islands/css-utils.ts +0 -565
  165. package/src/islands/discovery/index.ts +0 -80
  166. package/src/islands/discovery/registry.ts +0 -340
  167. package/src/islands/discovery/resolver.ts +0 -477
  168. package/src/islands/discovery/scanner.ts +0 -386
  169. package/src/islands/discovery/types.ts +0 -117
  170. package/src/islands/discovery/validator.ts +0 -544
  171. package/src/islands/discovery/watcher.ts +0 -368
  172. package/src/islands/framework-detection.ts +0 -428
  173. package/src/islands/integration-loader.ts +0 -490
  174. package/src/islands/island.tsx +0 -565
  175. package/src/islands/render-cache.ts +0 -550
  176. package/src/islands/types.ts +0 -80
  177. package/src/islands/universal-css-collector.ts +0 -157
  178. package/src/islands/universal-head-collector.ts +0 -137
  179. package/src/layout-system.ts +0 -218
  180. package/src/middleware/discovery.ts +0 -268
  181. package/src/middleware/executor.ts +0 -315
  182. package/src/middleware/index.ts +0 -76
  183. package/src/middleware/types.ts +0 -99
  184. package/src/nitro/build-config.ts +0 -576
  185. package/src/nitro/config.ts +0 -483
  186. package/src/nitro/error-handler.ts +0 -636
  187. package/src/nitro/index.ts +0 -173
  188. package/src/nitro/island-manifest.ts +0 -584
  189. package/src/nitro/middleware-adapter.ts +0 -260
  190. package/src/nitro/renderer.ts +0 -1471
  191. package/src/nitro/route-discovery.ts +0 -439
  192. package/src/nitro/types.ts +0 -321
  193. package/src/render/collect-css.ts +0 -198
  194. package/src/render/error-pages.ts +0 -79
  195. package/src/render/isolated-ssr-renderer.ts +0 -654
  196. package/src/render/ssr.ts +0 -1030
  197. package/src/schemas/api.ts +0 -30
  198. package/src/schemas/core.ts +0 -64
  199. package/src/schemas/index.ts +0 -212
  200. package/src/schemas/layout.ts +0 -279
  201. package/src/schemas/routing/index.ts +0 -38
  202. package/src/schemas/routing.ts +0 -376
  203. package/src/types/as-island.ts +0 -20
  204. package/src/types/layout.ts +0 -285
  205. package/src/types/routing.ts +0 -555
  206. package/src/types/types.ts +0 -5
  207. package/src/utils/dev-logger.ts +0 -299
  208. package/src/utils/fs.ts +0 -151
  209. package/src/vite-plugin/auto-discover.ts +0 -551
  210. package/src/vite-plugin/config.ts +0 -266
  211. package/src/vite-plugin/errors.ts +0 -127
  212. package/src/vite-plugin/image-optimization.ts +0 -156
  213. package/src/vite-plugin/integration-activator.ts +0 -126
  214. package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
  215. package/src/vite-plugin/module-discovery.ts +0 -189
  216. package/src/vite-plugin/nitro-integration.ts +0 -1354
  217. package/src/vite-plugin/plugin.ts +0 -403
  218. package/src/vite-plugin/types.ts +0 -327
  219. package/src/vite-plugin/validation.ts +0 -228
  220. /package/{src → dist/src}/client/types/framework-runtime.d.ts +0 -0
  221. /package/{src → dist/src}/client/types/vite-hmr.d.ts +0 -0
  222. /package/{src → dist/src}/client/types/vite-virtual-modules.d.ts +0 -0
  223. /package/{src → dist/src}/layout-system.d.ts +0 -0
  224. /package/{src → dist/src}/types/image.d.ts +0 -0
  225. /package/{src → dist/src}/types/index.d.ts +0 -0
  226. /package/{src → dist/src}/types/island-jsx.d.ts +0 -0
  227. /package/{src → dist/src}/types/island-prop.d.ts +0 -0
  228. /package/{src → dist/src}/types/mdx.d.ts +0 -0
  229. /package/{src → dist/src}/types/urlpattern.d.ts +0 -0
  230. /package/{src → dist/src}/types/vite-env.d.ts +0 -0
@@ -1,403 +0,0 @@
1
- /**
2
- * Avalon Vite Plugin
3
- *
4
- * This module provides the main `avalon()` function that creates a unified Vite plugin
5
- * for the Avalon framework. It handles configuration resolution, integration activation,
6
- * Nitro server integration, and wires up all the necessary Vite hooks.
7
- *
8
- * ISLAND DETECTION:
9
- * Islands are detected by usage - any component used with an `island` prop in pages
10
- * or layouts is automatically treated as an island. No fixed islands directory required.
11
- */
12
-
13
- import type { Plugin, PluginOption, ResolvedConfig, ViteDevServer } from 'vite';
14
- import type { AvalonPluginConfig, IntegrationName, ResolvedAvalonConfig } from './types.ts';
15
- import { createRequire } from 'node:module';
16
- import { dirname, join } from 'node:path';
17
- import { resolveConfig, checkDirectoriesExist } from './config.ts';
18
- import { activateIntegrations, activateSingleIntegration } from './integration-activator.ts';
19
- import { discoverIntegrationsFromIslandUsage } from './auto-discover.ts';
20
- import { validateActiveIntegrations, formatValidationResults } from './validation.ts';
21
- import { createMDXPlugin } from '../build/mdx-plugin.ts';
22
- import { mdxIslandTransform } from '../build/mdx-island-transform.ts';
23
- import { pageIslandTransform } from '../build/page-island-transform.ts';
24
- import { registry } from '../core/integrations/registry.ts';
25
- import { createNitroIntegration } from './nitro-integration.ts';
26
- import { islandSidecarPlugin } from './island-sidecar-plugin.ts';
27
- import { createImagePlugin } from './image-optimization.ts';
28
- import type { NitroConfigOutput } from '../nitro/config.ts';
29
- declare global {
30
- var __avalonConfig: ResolvedAvalonConfig | undefined;
31
- var __viteDevServer: ViteDevServer | undefined;
32
- var __nitroConfig: NitroConfigOutput | undefined;
33
- }
34
-
35
- /**
36
- * Collects Vite plugins from all activated integrations.
37
- *
38
- * This function iterates through the activated integrations and calls their
39
- * vitePlugin() method if implemented. The returned plugins are collected and
40
- * flattened into a single array.
41
- *
42
- * Plugin ordering is handled to ensure correct application:
43
- * - Lit plugins come first (DOM shim requirement)
44
- * - Other framework plugins follow
45
- *
46
- * @param activeIntegrations - Set of activated integration names
47
- * @param verbose - Whether to log detailed information
48
- * @returns Promise resolving to an array of Vite plugins from integrations
49
- */
50
- export async function collectIntegrationPlugins(
51
- activeIntegrations: Set<IntegrationName>,
52
- verbose: boolean = false,
53
- ): Promise<Plugin[]> {
54
- const plugins: Plugin[] = [];
55
- const litPlugins: Plugin[] = [];
56
-
57
- for (const name of activeIntegrations) {
58
- const validPlugins = await loadPluginsForIntegration(name, verbose);
59
- if (name === 'lit') {
60
- litPlugins.push(...validPlugins);
61
- } else {
62
- plugins.push(...validPlugins);
63
- }
64
- }
65
-
66
- return [...litPlugins, ...plugins];
67
- }
68
-
69
- async function loadPluginsForIntegration(name: IntegrationName, _verbose: boolean): Promise<Plugin[]> {
70
- const integration = registry.get(name);
71
- if (!integration) return [];
72
- if (typeof integration.vitePlugin !== 'function') return [];
73
-
74
- try {
75
- const result = await integration.vitePlugin();
76
- const pluginArray = Array.isArray(result) ? result : [result];
77
- return pluginArray.filter((p): p is Plugin => p != null);
78
- } catch (error) {
79
- console.warn(`[avalon] Failed to load vite plugin for ${name}:`, error instanceof Error ? error.message : error);
80
- return [];
81
- }
82
- }
83
-
84
- /**
85
- * Discovers which integrations are actually needed by scanning pages/layouts for island prop usage.
86
- * This enables lazy loading - only load Vite plugins for frameworks that are actually used.
87
- *
88
- * @param config - The resolved Avalon configuration
89
- * @param projectRoot - The project root directory (defaults to cwd)
90
- * @returns Set of integration names that are actually needed
91
- */
92
- async function discoverNeededIntegrations(
93
- config: ResolvedAvalonConfig,
94
- projectRoot?: string,
95
- ): Promise<Set<IntegrationName>> {
96
- const needed = new Set<IntegrationName>();
97
-
98
- try {
99
- // Scan pages, layouts, and modules for components used with island prop
100
- const discovered = await discoverIntegrationsFromIslandUsage(
101
- config.pagesDir,
102
- config.layoutsDir,
103
- projectRoot,
104
- config.modules?.dir,
105
- );
106
-
107
- // Only include integrations that are both discovered AND configured
108
- for (const integration of discovered) {
109
- if (config.integrations.includes(integration)) {
110
- needed.add(integration);
111
- }
112
- }
113
- } catch {
114
- // If discovery fails, fall back to all configured integrations
115
- for (const integration of config.integrations) {
116
- needed.add(integration);
117
- }
118
- }
119
-
120
- return needed;
121
- }
122
-
123
- async function resolveIntegrationsToLoad(preResolvedConfig: ResolvedAvalonConfig): Promise<IntegrationName[]> {
124
- if (!preResolvedConfig.lazyIntegrations || preResolvedConfig.integrations.length === 0) {
125
- return [...preResolvedConfig.integrations];
126
- }
127
-
128
- const needed = await discoverNeededIntegrations(preResolvedConfig);
129
- if (needed.size === 0) {
130
- return [...preResolvedConfig.integrations];
131
- }
132
-
133
- return Array.from(needed);
134
- }
135
-
136
- async function setupMDXPlugins(preResolvedConfig: ResolvedAvalonConfig): Promise<Plugin[]> {
137
- try {
138
- const mdxPlugins = await createMDXPlugin({
139
- jsxImportSource: preResolvedConfig.mdx.jsxImportSource,
140
- syntaxHighlighting: preResolvedConfig.mdx.syntaxHighlighting,
141
- remarkPlugins: preResolvedConfig.mdx.remarkPlugins as import('unified').Pluggable[],
142
- rehypePlugins: preResolvedConfig.mdx.rehypePlugins as import('unified').Pluggable[],
143
- development: true,
144
- });
145
- mdxPlugins.push(mdxIslandTransform({ verbose: preResolvedConfig.verbose }));
146
- return mdxPlugins;
147
- } catch (error) {
148
- if (preResolvedConfig.showWarnings) {
149
- console.warn('⚠️ Could not configure MDX plugin:', error);
150
- }
151
- return [];
152
- }
153
- }
154
-
155
- function setupNitroPlugins(
156
- preResolvedConfig: ResolvedAvalonConfig,
157
- nitroConfig: NonNullable<AvalonPluginConfig['nitro']>,
158
- _verbose?: boolean,
159
- ): { plugins: Plugin[]; options: NitroConfigOutput } {
160
- const { plugins, nitroOptions } = createNitroIntegration(preResolvedConfig, nitroConfig);
161
- globalThis.__nitroConfig = nitroOptions;
162
- return { plugins, options: nitroOptions };
163
- }
164
-
165
- async function runAutoDiscovery(
166
- resolvedConfig: ResolvedAvalonConfig,
167
- viteRoot: string,
168
- activeIntegrations: Set<IntegrationName>,
169
- ): Promise<void> {
170
- if (!resolvedConfig.autoDiscoverIntegrations) return;
171
-
172
- try {
173
- const discovered = await discoverIntegrationsFromIslandUsage(
174
- resolvedConfig.pagesDir,
175
- resolvedConfig.layoutsDir,
176
- viteRoot,
177
- resolvedConfig.modules?.dir,
178
- );
179
- for (const name of discovered) {
180
- if (activeIntegrations.has(name)) continue;
181
- try {
182
- await activateSingleIntegration(name, activeIntegrations, resolvedConfig.verbose);
183
- } catch (error) {
184
- if (resolvedConfig.showWarnings) console.warn(` ⚠️ Could not auto-load integration: ${name}`, error);
185
- }
186
- }
187
- } catch (error) {
188
- if (resolvedConfig.showWarnings) console.warn(' ⚠️ Auto-discovery failed:', error);
189
- }
190
- }
191
-
192
- function runValidation(resolvedConfig: ResolvedAvalonConfig, activeIntegrations: Set<IntegrationName>): void {
193
- if (!resolvedConfig.validateIntegrations || activeIntegrations.size === 0) return;
194
-
195
- const validationSummary = validateActiveIntegrations(activeIntegrations, resolvedConfig.showWarnings);
196
- if (!validationSummary.allValid) {
197
- console.error(formatValidationResults(validationSummary));
198
- if (resolvedConfig.showWarnings) console.warn(' ⚠️ Some integrations have validation issues.');
199
- }
200
- }
201
-
202
- /**
203
- * Creates the Avalon Vite plugin array
204
- *
205
- * @param config - Avalon configuration options
206
- * @returns A promise that resolves to an array of Vite plugins that handle all Avalon functionality.
207
- * Returns PluginOption[] to avoid TypeScript's excessive stack depth issues
208
- * when comparing Plugin<any> arrays in Vite 8's complex type system.
209
- */
210
- export async function avalon(config?: AvalonPluginConfig): Promise<PluginOption[]> {
211
- // Resolved configuration with defaults applied
212
- let resolvedConfig: ResolvedAvalonConfig;
213
-
214
- // Reference to Vite's resolved config
215
- let viteConfig: ResolvedConfig;
216
-
217
- // Track which integrations are activated
218
- const activeIntegrations = new Set<IntegrationName>();
219
-
220
- // Pre-resolve config to get MDX settings and integration list
221
- // We use isDev=true as a default; the actual value will be set in configResolved
222
- const preResolvedConfig = resolveConfig(config, true);
223
-
224
- const integrationsToLoad = await resolveIntegrationsToLoad(preResolvedConfig);
225
-
226
- if (integrationsToLoad.length > 0) {
227
- await activateIntegrations({ ...preResolvedConfig, integrations: integrationsToLoad }, activeIntegrations);
228
- }
229
- const mdxPlugins = await setupMDXPlugins(preResolvedConfig);
230
-
231
- // Image optimization plugins (vite-imagetools wrapper)
232
- const imagePlugins = await createImagePlugin(preResolvedConfig.image, preResolvedConfig.verbose);
233
-
234
- let integrationPlugins: Plugin[] = [];
235
- if (activeIntegrations.size > 0) {
236
- integrationPlugins = await collectIntegrationPlugins(activeIntegrations, preResolvedConfig.verbose);
237
- }
238
-
239
- let nitroPlugins: Plugin[] = [];
240
- if (config?.nitro) {
241
- const { plugins } = setupNitroPlugins(preResolvedConfig, config.nitro, preResolvedConfig.verbose);
242
- nitroPlugins = plugins;
243
- }
244
-
245
- // Sidecar plugin for Vue/Svelte/Solid type declarations
246
- const sidecarPlugin = islandSidecarPlugin({
247
- verbose: preResolvedConfig.verbose,
248
- });
249
-
250
- // Pre-resolve paths for standalone projects.
251
- // In the monorepo www/ project these are handled by manual resolve.alias.
252
- const require = createRequire(import.meta.url);
253
-
254
- let clientMainResolved: string | null = null;
255
- try {
256
- const clientEntry = require.resolve('@useavalon/avalon/client');
257
- clientMainResolved = join(dirname(clientEntry), 'main.js');
258
- } catch {
259
- // Monorepo — www/ sets its own alias
260
- }
261
-
262
- // Resolve /@useavalon/*/client and /@useavalon/*/client/hmr virtual imports
263
- // used by main.js. These are resolved dynamically in the resolveId hook
264
- // using Vite's resolver.
265
- const integrationVirtualIds = new Set(
266
- ['preact', 'react', 'vue', 'svelte', 'solid', 'lit', 'qwik'].flatMap(name => [
267
- `/@useavalon/${name}/client`,
268
- `/@useavalon/${name}/client/hmr`,
269
- ]),
270
- );
271
-
272
- // The main Avalon plugin
273
- const avalonPlugin: Plugin = {
274
- name: 'avalon',
275
- enforce: 'pre',
276
-
277
- config() {
278
- // @useavalon packages ship raw .ts source for SSR and pre-compiled
279
- // .js for client-side code.
280
- //
281
- // oxc.exclude: Prevents Vite's built-in OXC from processing @useavalon
282
- // .ts files. Without this, OXC applies integration plugins' global
283
- // jsx: 'automatic' config to plain .ts files, causing errors.
284
- // Our transform hook below handles TS stripping for SSR instead.
285
- // Client-side loads .js files which OXC skips by default (/\.js$/).
286
- //
287
- // ssr.noExternal: Ensures Vite processes @useavalon packages through
288
- // the SSR transform pipeline instead of treating them as external CJS.
289
- return {
290
- oxc: {
291
- exclude: [/node_modules\/@useavalon\/.*\.tsx?$/],
292
- },
293
- ssr: {
294
- noExternal: [/^@useavalon\//],
295
- },
296
- };
297
- },
298
-
299
- configResolved(resolvedViteConfig: ResolvedConfig) {
300
- viteConfig = resolvedViteConfig;
301
- const isDev = resolvedViteConfig.command === 'serve';
302
- resolvedConfig = resolveConfig(config, isDev);
303
-
304
- globalThis.__avalonConfig = resolvedConfig;
305
-
306
- checkDirectoriesExist(resolvedConfig, resolvedViteConfig.root);
307
- },
308
-
309
- async resolveId(id: string) {
310
- if (id === '/src/client/main.js' && clientMainResolved) {
311
- return clientMainResolved;
312
- }
313
- // /@useavalon/*/client and /@useavalon/*/client/hmr — resolve through
314
- // Vite's pipeline so it finds workspace-linked or npm-installed
315
- // integration packages from the consuming project's node_modules,
316
- // not from avalon's own context.
317
- if (integrationVirtualIds.has(id)) {
318
- const packageId = id.slice(1); // strip leading /
319
- const resolved = await this.resolve(packageId);
320
- return resolved?.id ?? null;
321
- }
322
- return null;
323
- },
324
-
325
- async transform(code: string, id: string) {
326
- // For SSR: strip TypeScript from @useavalon packages ourselves.
327
- // Integration plugins (react, preact) set jsx: 'automatic' which Vite's
328
- // OXC applies to all files — causing "Invalid jsx option" errors on
329
- // plain .ts files during SSR. We intercept and strip TS without JSX config.
330
- // For client-side: main.js imports pre-compiled .js files that OXC
331
- // skips entirely (default exclude: /\.js$/), avoiding the jsx conflict.
332
- if (this.environment?.config?.consumer === 'server' && id.includes('@useavalon/') && /\.tsx?$/.test(id)) {
333
- const { transform: oxcTransform } = await import('oxc-transform');
334
- const result = await oxcTransform(id, code, {
335
- sourcemap: true,
336
- typescript: { onlyRemoveTypeImports: false },
337
- });
338
- return { code: result.code, map: result.map, moduleType: 'js' };
339
- }
340
- },
341
-
342
- async buildStart() {
343
- await runAutoDiscovery(resolvedConfig, viteConfig?.root, activeIntegrations);
344
- runValidation(resolvedConfig, activeIntegrations);
345
- },
346
-
347
- configureServer(server: ViteDevServer) {
348
- (globalThis as any).__viteDevServer = server;
349
- },
350
- };
351
-
352
- // Extract Lit plugins for proper ordering
353
- const litPlugins = integrationPlugins.filter(p => p.name?.includes('lit'));
354
- const otherIntegrationPlugins = integrationPlugins.filter(p => !p.name?.includes('lit'));
355
-
356
- // Page island transform: auto-wraps components with `island` prop
357
- const pageTransformPlugin = pageIslandTransform({
358
- pagesDir: preResolvedConfig.pagesDir,
359
- layoutsDir: preResolvedConfig.layoutsDir,
360
- modules: preResolvedConfig.modules,
361
- verbose: preResolvedConfig.verbose,
362
- });
363
-
364
- return [
365
- pageTransformPlugin,
366
- ...imagePlugins,
367
- ...litPlugins,
368
- ...mdxPlugins,
369
- avalonPlugin,
370
- sidecarPlugin,
371
- ...nitroPlugins,
372
- ...otherIntegrationPlugins,
373
- ] as PluginOption[];
374
- }
375
-
376
- export function getResolvedConfig(): ResolvedAvalonConfig | undefined {
377
- return globalThis.__avalonConfig;
378
- }
379
-
380
- export function getPagesDir(): string {
381
- return globalThis.__avalonConfig?.pagesDir ?? 'src/pages';
382
- }
383
-
384
- export function getLayoutsDir(): string {
385
- return globalThis.__avalonConfig?.layoutsDir ?? 'src/layouts';
386
- }
387
-
388
- export function getNitroConfig(): NitroConfigOutput | undefined {
389
- return globalThis.__nitroConfig;
390
- }
391
-
392
- export function isNitroEnabled(): boolean {
393
- return globalThis.__nitroConfig !== undefined;
394
- }
395
-
396
- export type {
397
- AvalonPluginConfig,
398
- IntegrationName,
399
- ResolvedAvalonConfig,
400
- ImageConfig,
401
- ResolvedImageConfig,
402
- } from './types.ts';
403
- export type { AvalonNitroConfig, NitroConfigOutput } from '../nitro/config.ts';