@useavalon/avalon 0.1.10 → 0.1.12

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 (250) hide show
  1. package/README.md +54 -54
  2. package/dist/mod.js +1 -0
  3. package/dist/src/build/integration-bundler-plugin.js +1 -0
  4. package/dist/src/build/integration-config.js +1 -0
  5. package/dist/src/build/integration-detection-plugin.js +1 -0
  6. package/dist/src/build/integration-resolver-plugin.js +1 -0
  7. package/dist/src/build/island-manifest.js +1 -0
  8. package/dist/src/build/island-types-generator.js +5 -0
  9. package/dist/src/build/mdx-island-transform.js +2 -0
  10. package/dist/src/build/mdx-plugin.js +1 -0
  11. package/dist/src/build/page-island-transform.js +3 -0
  12. package/dist/src/build/prop-extractors/index.js +1 -0
  13. package/dist/src/build/prop-extractors/lit.js +1 -0
  14. package/dist/src/build/prop-extractors/qwik.js +1 -0
  15. package/dist/src/build/prop-extractors/solid.js +1 -0
  16. package/dist/src/build/prop-extractors/svelte.js +1 -0
  17. package/dist/src/build/prop-extractors/vue.js +1 -0
  18. package/dist/src/build/sidecar-file-manager.js +1 -0
  19. package/dist/src/build/sidecar-renderer.js +6 -0
  20. package/dist/src/client/adapters/index.js +1 -0
  21. package/dist/src/client/components.js +1 -0
  22. package/dist/src/client/css-hmr-handler.js +1 -0
  23. package/dist/src/client/framework-adapter.js +13 -0
  24. package/dist/src/client/hmr-coordinator.js +1 -0
  25. package/dist/src/client/hmr-error-overlay.js +214 -0
  26. package/dist/src/client/main.js +39 -0
  27. package/{src → dist/src}/client/types/framework-runtime.d.ts +68 -68
  28. package/{src → dist/src}/client/types/vite-hmr.d.ts +46 -46
  29. package/dist/src/client/types/vite-virtual-modules.d.ts +70 -0
  30. package/dist/src/components/Image.js +1 -0
  31. package/dist/src/components/IslandErrorBoundary.js +1 -0
  32. package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
  33. package/dist/src/components/LayoutErrorBoundary.js +1 -0
  34. package/dist/src/components/PersistentIsland.js +1 -0
  35. package/dist/src/components/StreamingErrorBoundary.js +1 -0
  36. package/dist/src/components/StreamingLayout.js +29 -0
  37. package/dist/src/core/components/component-analyzer.js +1 -0
  38. package/dist/src/core/components/component-detection.js +5 -0
  39. package/dist/src/core/components/enhanced-framework-detector.js +1 -0
  40. package/dist/src/core/components/framework-registry.js +1 -0
  41. package/dist/src/core/content/mdx-processor.js +1 -0
  42. package/dist/src/core/integrations/index.js +1 -0
  43. package/dist/src/core/integrations/loader.js +1 -0
  44. package/dist/src/core/integrations/registry.js +1 -0
  45. package/dist/src/core/islands/island-persistence.js +1 -0
  46. package/dist/src/core/islands/island-state-serializer.js +1 -0
  47. package/dist/src/core/islands/persistent-island-context.js +1 -0
  48. package/dist/src/core/islands/use-persistent-state.js +1 -0
  49. package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
  50. package/dist/src/core/layout/layout-cache-manager.js +1 -0
  51. package/dist/src/core/layout/layout-composer.js +1 -0
  52. package/dist/src/core/layout/layout-data-loader.js +1 -0
  53. package/dist/src/core/layout/layout-discovery.js +1 -0
  54. package/dist/src/core/layout/layout-matcher.js +1 -0
  55. package/dist/src/core/layout/layout-types.js +1 -0
  56. package/dist/src/core/modules/framework-module-resolver.js +1 -0
  57. package/dist/src/islands/component-analysis.js +1 -0
  58. package/dist/src/islands/css-utils.js +17 -0
  59. package/dist/src/islands/discovery/index.js +1 -0
  60. package/dist/src/islands/discovery/registry.js +1 -0
  61. package/dist/src/islands/discovery/resolver.js +2 -0
  62. package/dist/src/islands/discovery/scanner.js +1 -0
  63. package/dist/src/islands/discovery/types.js +1 -0
  64. package/dist/src/islands/discovery/validator.js +18 -0
  65. package/dist/src/islands/discovery/watcher.js +1 -0
  66. package/dist/src/islands/framework-detection.js +1 -0
  67. package/dist/src/islands/integration-loader.js +1 -0
  68. package/dist/src/islands/island.js +1 -0
  69. package/dist/src/islands/render-cache.js +1 -0
  70. package/dist/src/islands/types.js +1 -0
  71. package/dist/src/islands/universal-css-collector.js +5 -0
  72. package/dist/src/islands/universal-head-collector.js +2 -0
  73. package/{src → dist/src}/layout-system.d.ts +592 -592
  74. package/dist/src/layout-system.js +1 -0
  75. package/dist/src/middleware/discovery.js +1 -0
  76. package/dist/src/middleware/executor.js +1 -0
  77. package/dist/src/middleware/index.js +1 -0
  78. package/dist/src/middleware/types.js +1 -0
  79. package/dist/src/nitro/build-config.js +1 -0
  80. package/dist/src/nitro/config.js +1 -0
  81. package/dist/src/nitro/error-handler.js +198 -0
  82. package/dist/src/nitro/index.js +1 -0
  83. package/dist/src/nitro/island-manifest.js +2 -0
  84. package/dist/src/nitro/middleware-adapter.js +1 -0
  85. package/dist/src/nitro/renderer.js +183 -0
  86. package/dist/src/nitro/route-discovery.js +1 -0
  87. package/dist/src/nitro/types.js +1 -0
  88. package/dist/src/render/collect-css.js +3 -0
  89. package/{src/render/error-pages.ts → dist/src/render/error-pages.js} +7 -38
  90. package/dist/src/render/isolated-ssr-renderer.js +1 -0
  91. package/dist/src/render/ssr.js +90 -0
  92. package/dist/src/schemas/api.js +1 -0
  93. package/dist/src/schemas/core.js +1 -0
  94. package/dist/src/schemas/index.js +1 -0
  95. package/dist/src/schemas/layout.js +1 -0
  96. package/dist/src/schemas/routing/index.js +1 -0
  97. package/dist/src/schemas/routing.js +1 -0
  98. package/dist/src/types/as-island.js +1 -0
  99. package/{src → dist/src}/types/image.d.ts +106 -106
  100. package/{src → dist/src}/types/index.d.ts +22 -22
  101. package/{src → dist/src}/types/island-jsx.d.ts +33 -33
  102. package/{src → dist/src}/types/island-prop.d.ts +20 -20
  103. package/dist/src/types/layout.js +1 -0
  104. package/{src → dist/src}/types/mdx.d.ts +6 -6
  105. package/dist/src/types/routing.js +1 -0
  106. package/dist/src/types/types.js +1 -0
  107. package/{src → dist/src}/types/urlpattern.d.ts +49 -49
  108. package/{src → dist/src}/types/vite-env.d.ts +11 -11
  109. package/dist/src/utils/dev-logger.js +12 -0
  110. package/dist/src/utils/fs.js +1 -0
  111. package/dist/src/vite-plugin/auto-discover.js +1 -0
  112. package/dist/src/vite-plugin/config.js +1 -0
  113. package/dist/src/vite-plugin/errors.js +1 -0
  114. package/dist/src/vite-plugin/image-optimization.js +45 -0
  115. package/dist/src/vite-plugin/integration-activator.js +1 -0
  116. package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
  117. package/dist/src/vite-plugin/module-discovery.js +1 -0
  118. package/dist/src/vite-plugin/nitro-integration.js +42 -0
  119. package/dist/src/vite-plugin/plugin.js +1 -0
  120. package/dist/src/vite-plugin/types.js +1 -0
  121. package/dist/src/vite-plugin/validation.js +2 -0
  122. package/package.json +57 -26
  123. package/mod.ts +0 -302
  124. package/src/build/integration-bundler-plugin.ts +0 -116
  125. package/src/build/integration-config.ts +0 -168
  126. package/src/build/integration-detection-plugin.ts +0 -117
  127. package/src/build/integration-resolver-plugin.ts +0 -90
  128. package/src/build/island-manifest.ts +0 -269
  129. package/src/build/island-types-generator.ts +0 -476
  130. package/src/build/mdx-island-transform.ts +0 -464
  131. package/src/build/mdx-plugin.ts +0 -98
  132. package/src/build/page-island-transform.ts +0 -598
  133. package/src/build/prop-extractors/index.ts +0 -21
  134. package/src/build/prop-extractors/lit.ts +0 -140
  135. package/src/build/prop-extractors/qwik.ts +0 -16
  136. package/src/build/prop-extractors/solid.ts +0 -125
  137. package/src/build/prop-extractors/svelte.ts +0 -194
  138. package/src/build/prop-extractors/vue.ts +0 -111
  139. package/src/build/sidecar-file-manager.ts +0 -104
  140. package/src/build/sidecar-renderer.ts +0 -30
  141. package/src/client/adapters/index.js +0 -12
  142. package/src/client/adapters/index.ts +0 -13
  143. package/src/client/adapters/lit-adapter.js +0 -467
  144. package/src/client/adapters/lit-adapter.ts +0 -654
  145. package/src/client/adapters/preact-adapter.js +0 -223
  146. package/src/client/adapters/preact-adapter.ts +0 -331
  147. package/src/client/adapters/qwik-adapter.js +0 -259
  148. package/src/client/adapters/qwik-adapter.ts +0 -345
  149. package/src/client/adapters/react-adapter.js +0 -220
  150. package/src/client/adapters/react-adapter.ts +0 -353
  151. package/src/client/adapters/solid-adapter.js +0 -295
  152. package/src/client/adapters/solid-adapter.ts +0 -451
  153. package/src/client/adapters/svelte-adapter.js +0 -368
  154. package/src/client/adapters/svelte-adapter.ts +0 -524
  155. package/src/client/adapters/vue-adapter.js +0 -278
  156. package/src/client/adapters/vue-adapter.ts +0 -467
  157. package/src/client/components.js +0 -23
  158. package/src/client/components.ts +0 -35
  159. package/src/client/css-hmr-handler.js +0 -263
  160. package/src/client/css-hmr-handler.ts +0 -344
  161. package/src/client/framework-adapter.js +0 -283
  162. package/src/client/framework-adapter.ts +0 -462
  163. package/src/client/hmr-coordinator.js +0 -274
  164. package/src/client/hmr-coordinator.ts +0 -396
  165. package/src/client/hmr-error-overlay.js +0 -533
  166. package/src/client/main.js +0 -816
  167. package/src/client/types/vite-virtual-modules.d.ts +0 -60
  168. package/src/components/Image.tsx +0 -123
  169. package/src/components/IslandErrorBoundary.tsx +0 -145
  170. package/src/components/LayoutDataErrorBoundary.tsx +0 -141
  171. package/src/components/LayoutErrorBoundary.tsx +0 -127
  172. package/src/components/PersistentIsland.tsx +0 -52
  173. package/src/components/StreamingErrorBoundary.tsx +0 -233
  174. package/src/components/StreamingLayout.tsx +0 -538
  175. package/src/core/components/component-analyzer.ts +0 -192
  176. package/src/core/components/component-detection.ts +0 -508
  177. package/src/core/components/enhanced-framework-detector.ts +0 -500
  178. package/src/core/components/framework-registry.ts +0 -563
  179. package/src/core/content/mdx-processor.ts +0 -46
  180. package/src/core/integrations/index.ts +0 -19
  181. package/src/core/integrations/loader.ts +0 -125
  182. package/src/core/integrations/registry.ts +0 -175
  183. package/src/core/islands/island-persistence.ts +0 -325
  184. package/src/core/islands/island-state-serializer.ts +0 -258
  185. package/src/core/islands/persistent-island-context.tsx +0 -80
  186. package/src/core/islands/use-persistent-state.ts +0 -68
  187. package/src/core/layout/enhanced-layout-resolver.ts +0 -322
  188. package/src/core/layout/layout-cache-manager.ts +0 -485
  189. package/src/core/layout/layout-composer.ts +0 -357
  190. package/src/core/layout/layout-data-loader.ts +0 -516
  191. package/src/core/layout/layout-discovery.ts +0 -243
  192. package/src/core/layout/layout-matcher.ts +0 -299
  193. package/src/core/layout/layout-types.ts +0 -110
  194. package/src/core/modules/framework-module-resolver.ts +0 -273
  195. package/src/islands/component-analysis.ts +0 -213
  196. package/src/islands/css-utils.ts +0 -565
  197. package/src/islands/discovery/index.ts +0 -80
  198. package/src/islands/discovery/registry.ts +0 -340
  199. package/src/islands/discovery/resolver.ts +0 -477
  200. package/src/islands/discovery/scanner.ts +0 -386
  201. package/src/islands/discovery/types.ts +0 -117
  202. package/src/islands/discovery/validator.ts +0 -544
  203. package/src/islands/discovery/watcher.ts +0 -368
  204. package/src/islands/framework-detection.ts +0 -428
  205. package/src/islands/integration-loader.ts +0 -490
  206. package/src/islands/island.tsx +0 -565
  207. package/src/islands/render-cache.ts +0 -550
  208. package/src/islands/types.ts +0 -80
  209. package/src/islands/universal-css-collector.ts +0 -157
  210. package/src/islands/universal-head-collector.ts +0 -137
  211. package/src/layout-system.ts +0 -218
  212. package/src/middleware/discovery.ts +0 -268
  213. package/src/middleware/executor.ts +0 -315
  214. package/src/middleware/index.ts +0 -76
  215. package/src/middleware/types.ts +0 -99
  216. package/src/nitro/build-config.ts +0 -576
  217. package/src/nitro/config.ts +0 -483
  218. package/src/nitro/error-handler.ts +0 -636
  219. package/src/nitro/index.ts +0 -173
  220. package/src/nitro/island-manifest.ts +0 -584
  221. package/src/nitro/middleware-adapter.ts +0 -260
  222. package/src/nitro/renderer.ts +0 -1471
  223. package/src/nitro/route-discovery.ts +0 -439
  224. package/src/nitro/types.ts +0 -321
  225. package/src/render/collect-css.ts +0 -198
  226. package/src/render/isolated-ssr-renderer.ts +0 -654
  227. package/src/render/ssr.ts +0 -1030
  228. package/src/schemas/api.ts +0 -30
  229. package/src/schemas/core.ts +0 -64
  230. package/src/schemas/index.ts +0 -212
  231. package/src/schemas/layout.ts +0 -279
  232. package/src/schemas/routing/index.ts +0 -38
  233. package/src/schemas/routing.ts +0 -376
  234. package/src/types/as-island.ts +0 -20
  235. package/src/types/layout.ts +0 -285
  236. package/src/types/routing.ts +0 -555
  237. package/src/types/types.ts +0 -5
  238. package/src/utils/dev-logger.ts +0 -299
  239. package/src/utils/fs.ts +0 -151
  240. package/src/vite-plugin/auto-discover.ts +0 -551
  241. package/src/vite-plugin/config.ts +0 -266
  242. package/src/vite-plugin/errors.ts +0 -127
  243. package/src/vite-plugin/image-optimization.ts +0 -156
  244. package/src/vite-plugin/integration-activator.ts +0 -126
  245. package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
  246. package/src/vite-plugin/module-discovery.ts +0 -189
  247. package/src/vite-plugin/nitro-integration.ts +0 -1354
  248. package/src/vite-plugin/plugin.ts +0 -401
  249. package/src/vite-plugin/types.ts +0 -327
  250. package/src/vite-plugin/validation.ts +0 -228
@@ -1,467 +0,0 @@
1
- /**
2
- * Vue HMR Adapter
3
- *
4
- * Provides Hot Module Replacement support for Vue 3 components.
5
- * Integrates with @vitejs/plugin-vue to preserve reactive state during updates.
6
- * Uses Vue's __VUE_HMR_RUNTIME__ API for hot updates.
7
- *
8
- * Requirements: 2.3
9
- */
10
-
11
- /// <reference lib="dom" />
12
-
13
- import { BaseFrameworkAdapter, type StateSnapshot } from '../framework-adapter.ts';
14
-
15
- /**
16
- * Vue component type
17
- * Can be a component options object or a setup function
18
- */
19
- type VueComponent<P = Record<string, unknown>> =
20
- | VueComponentOptions<P>
21
- | ((props: P) => unknown);
22
-
23
- /**
24
- * Vue component options interface
25
- */
26
- interface VueComponentOptions<P = Record<string, unknown>> {
27
- name?: string;
28
- props?: string[] | Record<string, unknown>;
29
- data?: () => Record<string, unknown>;
30
- setup?: (props: P, context: unknown) => unknown;
31
- render?: () => unknown;
32
- template?: string;
33
- components?: Record<string, VueComponent>;
34
- computed?: Record<string, () => unknown>;
35
- methods?: Record<string, (...args: unknown[]) => unknown>;
36
- watch?: Record<string, unknown>;
37
- // Vue 3 specific
38
- emits?: string[] | Record<string, unknown>;
39
- expose?: string[];
40
- // Lifecycle hooks
41
- beforeCreate?: () => void;
42
- created?: () => void;
43
- beforeMount?: () => void;
44
- mounted?: () => void;
45
- beforeUpdate?: () => void;
46
- updated?: () => void;
47
- beforeUnmount?: () => void;
48
- unmounted?: () => void;
49
- }
50
-
51
- /**
52
- * Vue App instance interface
53
- */
54
- interface VueApp {
55
- mount(rootContainer: HTMLElement | string, isHydrate?: boolean): unknown;
56
- unmount(): void;
57
- use(plugin: unknown, ...options: unknown[]): this;
58
- component(name: string, component: VueComponent): this;
59
- directive(name: string, directive: unknown): this;
60
- provide(key: string | symbol, value: unknown): this;
61
- config: {
62
- errorHandler?: (err: Error, instance: unknown, info: string) => void;
63
- warnHandler?: (msg: string, instance: unknown, trace: string) => void;
64
- };
65
- }
66
-
67
- /**
68
- * Vue module interface
69
- */
70
- interface VueModule {
71
- createApp(rootComponent: VueComponent, rootProps?: Record<string, unknown>): VueApp;
72
- version: string;
73
- }
74
-
75
- /**
76
- * Vue HMR Runtime interface
77
- * Provided by @vitejs/plugin-vue for hot module replacement
78
- */
79
- interface VueHMRRuntime {
80
- /**
81
- * Create a record for a component
82
- */
83
- createRecord(id: string, component: VueComponent): boolean;
84
-
85
- /**
86
- * Reload a component (full reload)
87
- */
88
- reload(id: string, component: VueComponent): void;
89
-
90
- /**
91
- * Rerender a component (template only)
92
- */
93
- rerender(id: string, render: () => unknown): void;
94
- }
95
-
96
- /**
97
- * Global Vue HMR runtime
98
- * Injected by @vitejs/plugin-vue
99
- */
100
- declare global {
101
- var __VUE_HMR_RUNTIME__: VueHMRRuntime | undefined;
102
- }
103
-
104
- /**
105
- * Vue-specific state snapshot
106
- * Extends base snapshot with Vue-specific reactive state
107
- */
108
- interface VueStateSnapshot extends StateSnapshot {
109
- framework: 'vue';
110
- data: {
111
- /**
112
- * Vue reactive data
113
- * Captured from component instance
114
- */
115
- reactiveData?: Record<string, unknown>;
116
-
117
- /**
118
- * Component display name for debugging
119
- */
120
- componentName?: string;
121
-
122
- /**
123
- * Props at time of state capture
124
- */
125
- capturedProps?: Record<string, unknown>;
126
-
127
- /**
128
- * Computed properties values
129
- */
130
- computedValues?: Record<string, unknown>;
131
- };
132
- }
133
-
134
- /**
135
- * Vue HMR Adapter
136
- *
137
- * Leverages Vue's HMR capabilities (provided by @vitejs/plugin-vue) to:
138
- * - Preserve reactive state across updates
139
- * - Maintain computed properties
140
- * - Handle component updates without full remount
141
- *
142
- * Vue HMR works through the __VUE_HMR_RUNTIME__ API:
143
- * 1. When a component module is updated, Vite sends an HMR event
144
- * 2. We use __VUE_HMR_RUNTIME__.reload() to hot-reload the component
145
- * 3. Vue preserves reactive state automatically through its reactivity system
146
- * 4. The component re-renders with preserved state
147
- */
148
- export class VueHMRAdapter extends BaseFrameworkAdapter {
149
- readonly name = 'vue';
150
-
151
- /**
152
- * Store Vue app instances for each island to enable proper updates
153
- */
154
- private apps: WeakMap<HTMLElement, VueApp> = new WeakMap();
155
-
156
- /**
157
- * Store component IDs for HMR runtime
158
- */
159
- private componentIds: WeakMap<HTMLElement, string> = new WeakMap();
160
-
161
- /**
162
- * Check if a component is a Vue component
163
- *
164
- * Vue components can be:
165
- * - Component options objects (with setup, data, render, template, etc.)
166
- * - Setup functions (Composition API)
167
- * - SFC compiled components
168
- */
169
- canHandle(component: unknown): boolean {
170
- if (!component) return false;
171
-
172
- // Check if it's a function (setup function or render function)
173
- if (typeof component === 'function') {
174
- // Vue setup functions or render functions
175
- return true;
176
- }
177
-
178
- // Check if it's a component options object
179
- if (typeof component !== 'object') {
180
- return false;
181
- }
182
-
183
- const obj = component as Record<string, unknown>;
184
-
185
- // Check for Vue-specific properties
186
- const hasVueProperties =
187
- 'setup' in obj ||
188
- 'data' in obj ||
189
- 'render' in obj ||
190
- 'template' in obj ||
191
- 'props' in obj ||
192
- 'computed' in obj ||
193
- 'methods' in obj ||
194
- 'components' in obj ||
195
- 'emits' in obj ||
196
- // Lifecycle hooks
197
- 'mounted' in obj ||
198
- 'created' in obj ||
199
- 'beforeMount' in obj ||
200
- 'beforeCreate' in obj;
201
-
202
- if (hasVueProperties) {
203
- return true;
204
- }
205
-
206
- // Check for __vccOpts (Vue SFC compiled component marker)
207
- if ('__vccOpts' in obj) {
208
- return true;
209
- }
210
-
211
- return false;
212
- }
213
-
214
- /**
215
- * Preserve Vue component state before HMR update
216
- *
217
- * Vue's reactivity system handles most state preservation automatically.
218
- * We capture additional DOM state and props for fallback.
219
- */
220
- override preserveState(island: HTMLElement): VueStateSnapshot | null {
221
- try {
222
- // Get base DOM state
223
- const baseSnapshot = super.preserveState(island);
224
- if (!baseSnapshot) return null;
225
-
226
- // Get Vue-specific data
227
- const propsAttr = island.getAttribute('data-props');
228
- const capturedProps = propsAttr ? JSON.parse(propsAttr) : {};
229
-
230
- // Try to get component name from the island
231
- const src = island.getAttribute('data-src') || '';
232
- const componentName = this.extractComponentName(src);
233
-
234
- // Try to capture reactive data from the Vue instance
235
- // Note: This is best-effort, as Vue's internal state is not easily accessible
236
- // Vue's HMR runtime will handle most state preservation automatically
237
- const reactiveData = this.captureReactiveData(island);
238
-
239
- const vueSnapshot: VueStateSnapshot = {
240
- ...baseSnapshot,
241
- framework: 'vue',
242
- data: {
243
- componentName,
244
- capturedProps,
245
- reactiveData,
246
- },
247
- };
248
-
249
- return vueSnapshot;
250
- } catch (error) {
251
- console.warn('Failed to preserve Vue state:', error);
252
- return null;
253
- }
254
- }
255
-
256
- /**
257
- * Update Vue component with HMR
258
- *
259
- * This method integrates with Vue's HMR API:
260
- * 1. Vue HMR is automatically enabled by @vitejs/plugin-vue
261
- * 2. When a module updates, Vite sends an HMR event
262
- * 3. We use __VUE_HMR_RUNTIME__ to reload the component
263
- * 4. Vue preserves reactive state automatically
264
- * 5. The component re-renders with preserved state
265
- */
266
- async update(
267
- island: HTMLElement,
268
- newComponent: unknown,
269
- props: Record<string, unknown>
270
- ): Promise<void> {
271
- if (!this.canHandle(newComponent)) {
272
- throw new Error('Component is not a valid Vue component');
273
- }
274
-
275
- const Component = newComponent as VueComponent;
276
-
277
- try {
278
- // Dynamically import Vue at runtime
279
- // This is resolved by Vite in the browser
280
- const vueModule = await import('vue') as VueModule;
281
- const { createApp } = vueModule;
282
-
283
- // Check if we have an existing app
284
- const existingApp = this.apps.get(island);
285
- const componentId = this.componentIds.get(island);
286
-
287
- // Try to use Vue HMR runtime if available
288
- const hmrRuntime = globalThis.__VUE_HMR_RUNTIME__;
289
-
290
- if (hmrRuntime && componentId) {
291
- // Use Vue's HMR runtime for hot reload
292
- // This preserves reactive state automatically
293
- try {
294
- hmrRuntime.reload(componentId, Component);
295
-
296
- // If we have an existing app, we're done
297
- // Vue HMR runtime handles the update
298
- if (existingApp) {
299
- return;
300
- }
301
- } catch (error) {
302
- console.warn('Vue HMR runtime reload failed, falling back to full remount:', error);
303
- }
304
- }
305
-
306
- if (existingApp) {
307
- // Unmount existing app
308
- try {
309
- existingApp.unmount();
310
- } catch (error) {
311
- console.warn('Failed to unmount existing Vue app:', error);
312
- }
313
- }
314
-
315
- // Create new app and mount
316
- const app = createApp(Component, props);
317
-
318
- // Configure error handling
319
- app.config.errorHandler = (err: Error, _instance: unknown, info: string) => {
320
- console.error('Vue component error during HMR:', err, info);
321
- };
322
-
323
- // Mount with hydration
324
- app.mount(island, true);
325
-
326
- // Store app and component ID for future updates
327
- this.apps.set(island, app);
328
-
329
- // Generate component ID for HMR runtime
330
- const src = island.getAttribute('data-src') || '';
331
- const newComponentId = this.generateComponentId(src);
332
- this.componentIds.set(island, newComponentId);
333
-
334
- // Register with HMR runtime if available
335
- if (hmrRuntime) {
336
- hmrRuntime.createRecord(newComponentId, Component);
337
- }
338
-
339
- // Mark as hydrated
340
- island.setAttribute('data-hydrated', 'true');
341
- island.setAttribute('data-hydration-status', 'success');
342
-
343
- } catch (error) {
344
- console.error('Vue HMR update failed:', error);
345
- island.setAttribute('data-hydration-status', 'error');
346
- throw error;
347
- }
348
- }
349
-
350
- /**
351
- * Restore Vue component state after HMR update
352
- *
353
- * Vue's reactivity system handles most state restoration automatically.
354
- * We restore DOM state (scroll, focus, form values) as a supplement.
355
- */
356
- override restoreState(island: HTMLElement, state: StateSnapshot): void {
357
- try {
358
- // Restore DOM state (scroll, focus, form values)
359
- super.restoreState(island, state);
360
-
361
- // Vue's reactivity system handles reactive state restoration automatically
362
- // through the HMR runtime, so we don't need to do anything special here
363
-
364
- } catch (error) {
365
- console.warn('Failed to restore Vue state:', error);
366
- }
367
- }
368
-
369
- /**
370
- * Handle errors during Vue HMR update
371
- *
372
- * Provides Vue-specific error handling with helpful messages
373
- */
374
- override handleError(island: HTMLElement, error: Error): void {
375
- console.error('Vue HMR error:', error);
376
-
377
- // Use base error handling
378
- super.handleError(island, error);
379
-
380
- // Add Vue-specific error information
381
- const errorIndicator = island.querySelector('.hmr-error-indicator');
382
- if (errorIndicator) {
383
- const errorMessage = error.message;
384
-
385
- // Provide helpful hints for common Vue errors
386
- let hint = '';
387
- if (errorMessage.includes('reactive') || errorMessage.includes('ref')) {
388
- hint = ' (Hint: Check reactive state usage - refs must be accessed with .value)';
389
- } else if (errorMessage.includes('render')) {
390
- hint = ' (Hint: Check component render function or template for errors)';
391
- } else if (errorMessage.includes('hydration') || errorMessage.includes('mismatch')) {
392
- hint = ' (Hint: Server and client render must match)';
393
- } else if (errorMessage.includes('setup')) {
394
- hint = ' (Hint: Check setup function - it should return render function or object)';
395
- }
396
-
397
- errorIndicator.textContent = `Vue HMR Error: ${errorMessage}${hint}`;
398
- }
399
- }
400
-
401
- /**
402
- * Extract component name from source path
403
- * Used for debugging and error messages
404
- */
405
- private extractComponentName(src: string): string {
406
- const parts = src.split('/');
407
- const filename = parts[parts.length - 1];
408
- return filename.replace(/\.(vue|tsx?|jsx?)$/, '');
409
- }
410
-
411
- /**
412
- * Generate a unique component ID for HMR runtime
413
- */
414
- private generateComponentId(src: string): string {
415
- // Use the source path as the component ID
416
- // This ensures consistency across HMR updates
417
- return src.replace(/[^a-zA-Z0-9]/g, '_');
418
- }
419
-
420
- /**
421
- * Attempt to capture reactive data from Vue instance
422
- * This is best-effort and may not work in all cases
423
- */
424
- private captureReactiveData(island: HTMLElement): Record<string, unknown> | undefined {
425
- try {
426
- // Vue 3 stores instance data on the element's __vueParentComponent
427
- // This is internal API and may change, so we wrap in try-catch
428
- const vueInstance = (island as unknown as { __vueParentComponent?: unknown }).__vueParentComponent;
429
-
430
- if (vueInstance && typeof vueInstance === 'object') {
431
- // Try to extract data from the instance
432
- // This is very fragile and depends on Vue internals
433
- const data = (vueInstance as { data?: Record<string, unknown> }).data;
434
- if (data && typeof data === 'object') {
435
- return { ...data };
436
- }
437
- }
438
- } catch (error) {
439
- // Silently fail - this is best-effort
440
- console.debug('Could not capture Vue reactive data:', error);
441
- }
442
-
443
- return undefined;
444
- }
445
-
446
- /**
447
- * Clean up Vue app when island is removed
448
- * This should be called when an island is unmounted
449
- */
450
- unmount(island: HTMLElement): void {
451
- const app = this.apps.get(island);
452
- if (app) {
453
- try {
454
- app.unmount();
455
- this.apps.delete(island);
456
- this.componentIds.delete(island);
457
- } catch (error) {
458
- console.warn('Failed to unmount Vue app:', error);
459
- }
460
- }
461
- }
462
- }
463
-
464
- /**
465
- * Create and export a singleton instance of the Vue HMR adapter
466
- */
467
- export const vueAdapter = new VueHMRAdapter();
@@ -1,23 +0,0 @@
1
- /**
2
- * Client-safe component exports for use in island components.
3
- *
4
- * Import from '@useavalon/avalon/client' instead of '@useavalon/avalon' when
5
- * you need framework components inside islands. The main entry point
6
- * re-exports server-only code (nitro, h3, vite plugins) that can't
7
- * be bundled for the browser.
8
- */
9
- // Persistent islands
10
- export { PersistentIsland } from "../components/PersistentIsland.tsx";
11
- export { usePersistentIslandContext, PersistentIslandProvider, createPersistentIslandContext } from "../core/islands/persistent-island-context.tsx";
12
- export { usePersistentState } from "../core/islands/use-persistent-state.js";
13
- export { IslandPersistence, defaultIslandPersistence } from "../core/islands/island-persistence.js";
14
- export { IslandStateSerializer } from "../core/islands/island-state-serializer.js";
15
- // Error boundaries
16
- export { IslandErrorBoundary, withIslandErrorBoundary } from "../components/IslandErrorBoundary.tsx";
17
- export { LayoutErrorBoundary } from "../components/LayoutErrorBoundary.tsx";
18
- export { LayoutDataErrorBoundary } from "../components/LayoutDataErrorBoundary.tsx";
19
- export { StreamingErrorBoundary, withStreamingErrorBoundary } from "../components/StreamingErrorBoundary.tsx";
20
- // Streaming
21
- export { StreamingLayout, StreamingSuspense, withStreaming, useStreamingState } from "../components/StreamingLayout.tsx";
22
- // Image optimization
23
- export { Image } from "../components/Image.tsx";
@@ -1,35 +0,0 @@
1
- /**
2
- * Client-safe component exports for use in island components.
3
- *
4
- * Import from '@useavalon/avalon/client' instead of '@useavalon/avalon' when
5
- * you need framework components inside islands. The main entry point
6
- * re-exports server-only code (nitro, h3, vite plugins) that can't
7
- * be bundled for the browser.
8
- */
9
-
10
- // Persistent islands
11
- export { PersistentIsland } from '../components/PersistentIsland.tsx';
12
- export {
13
- usePersistentIslandContext,
14
- PersistentIslandProvider,
15
- createPersistentIslandContext,
16
- } from '../core/islands/persistent-island-context.tsx';
17
- export { usePersistentState } from '../core/islands/use-persistent-state.ts';
18
- export { IslandPersistence, defaultIslandPersistence } from '../core/islands/island-persistence.ts';
19
- export { IslandStateSerializer } from '../core/islands/island-state-serializer.ts';
20
-
21
- // Error boundaries
22
- export { IslandErrorBoundary, withIslandErrorBoundary } from '../components/IslandErrorBoundary.tsx';
23
- export { LayoutErrorBoundary } from '../components/LayoutErrorBoundary.tsx';
24
- export { LayoutDataErrorBoundary } from '../components/LayoutDataErrorBoundary.tsx';
25
- export { StreamingErrorBoundary, withStreamingErrorBoundary } from '../components/StreamingErrorBoundary.tsx';
26
-
27
- // Streaming
28
- export { StreamingLayout, StreamingSuspense, withStreaming, useStreamingState } from '../components/StreamingLayout.tsx';
29
-
30
- // Image optimization
31
- export { Image } from '../components/Image.tsx';
32
- export type { ImageProps } from '../components/Image.tsx';
33
-
34
- // Types
35
- export type { IslandState } from '../schemas/layout.ts';