@useavalon/avalon 0.1.5 → 0.1.6

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 (31) hide show
  1. package/package.json +31 -58
  2. package/src/build/README.md +0 -310
  3. package/src/client/tests/css-hmr-handler.test.ts +0 -360
  4. package/src/client/tests/framework-adapter.test.ts +0 -519
  5. package/src/client/tests/hmr-coordinator.test.ts +0 -176
  6. package/src/client/tests/hydration-option-parsing.test.ts +0 -107
  7. package/src/client/tests/lit-adapter.test.ts +0 -427
  8. package/src/client/tests/preact-adapter.test.ts +0 -353
  9. package/src/client/tests/qwik-adapter.test.ts +0 -343
  10. package/src/client/tests/react-adapter.test.ts +0 -317
  11. package/src/client/tests/solid-adapter.test.ts +0 -396
  12. package/src/client/tests/svelte-adapter.test.ts +0 -387
  13. package/src/client/tests/vue-adapter.test.ts +0 -407
  14. package/src/components/tests/component-analyzer.test.ts +0 -96
  15. package/src/components/tests/component-detection.test.ts +0 -347
  16. package/src/components/tests/persistent-islands.test.ts +0 -398
  17. package/src/core/components/tests/enhanced-framework-detector.test.ts +0 -577
  18. package/src/core/components/tests/framework-registry.test.ts +0 -465
  19. package/src/core/integrations/README.md +0 -282
  20. package/src/core/layout/tests/enhanced-layout-resolver.test.ts +0 -477
  21. package/src/core/layout/tests/layout-cache-optimization.test.ts +0 -149
  22. package/src/core/layout/tests/layout-composer.test.ts +0 -486
  23. package/src/core/layout/tests/layout-data-loader.test.ts +0 -443
  24. package/src/core/layout/tests/layout-discovery.test.ts +0 -253
  25. package/src/core/layout/tests/layout-matcher.test.ts +0 -480
  26. package/src/core/modules/tests/framework-module-resolver.test.ts +0 -263
  27. package/src/core/modules/tests/module-resolution-integration.test.ts +0 -117
  28. package/src/islands/discovery/tests/island-discovery.test.ts +0 -881
  29. package/src/middleware/__tests__/discovery.test.ts +0 -107
  30. package/src/types/tests/layout-types.test.ts +0 -197
  31. package/src/vite-plugin/tests/image-optimization.test.ts +0 -54
@@ -1,407 +0,0 @@
1
- /**
2
- * Tests for Vue HMR Adapter
3
- *
4
- * Verifies Vue-specific HMR functionality including:
5
- * - Component detection
6
- * - State preservation
7
- * - Vue HMR runtime integration
8
- * - Error handling
9
- *
10
- * Requirements: 2.3
11
- */
12
-
13
- import { describe, it, expect } from 'vitest';
14
- import { VueHMRAdapter } from '../adapters/vue-adapter.ts';
15
- import type { StateSnapshot } from '../framework-adapter.ts';
16
-
17
- // Mock HTMLElement for testing
18
- class MockHTMLElement {
19
- private attributes: Map<string, string> = new Map();
20
- private _children: MockHTMLElement[] = [];
21
- public scrollTop = 0;
22
- public scrollLeft = 0;
23
- public style: Record<string, string> = {};
24
-
25
- getAttribute(name: string): string | null {
26
- return this.attributes.get(name) || null;
27
- }
28
-
29
- setAttribute(name: string, value: string): void {
30
- this.attributes.set(name, value);
31
- }
32
-
33
- removeAttribute(name: string): void {
34
- this.attributes.delete(name);
35
- }
36
-
37
- hasAttribute(name: string): boolean {
38
- return this.attributes.has(name);
39
- }
40
-
41
- querySelector(selector: string): MockHTMLElement | null {
42
- return null;
43
- }
44
-
45
- querySelectorAll(selector: string): MockHTMLElement[] {
46
- return [];
47
- }
48
-
49
- contains(element: unknown): boolean {
50
- return false;
51
- }
52
-
53
- insertBefore(newNode: unknown, referenceNode: unknown): void {
54
- // Mock implementation
55
- }
56
-
57
- get firstChild(): unknown {
58
- return null;
59
- }
60
-
61
- dispatchEvent(event: any): boolean {
62
- return true;
63
- }
64
- }
65
-
66
- // Mock Vue components for testing
67
- const MockVueOptionsComponent = {
68
- name: 'TestComponent',
69
- props: ['count'],
70
- data() {
71
- return {
72
- internalState: 0,
73
- };
74
- },
75
- template: '<div>{{ count }}</div>',
76
- };
77
-
78
- const MockVueSetupComponent = {
79
- name: 'SetupComponent',
80
- setup(props: Record<string, unknown>) {
81
- return () => null;
82
- },
83
- };
84
-
85
- function MockVueSetupFunction(props: Record<string, unknown>) {
86
- return () => null;
87
- }
88
-
89
- const MockVueSFCComponent = {
90
- __vccOpts: {
91
- name: 'SFCComponent',
92
- },
93
- render() {
94
- return null;
95
- },
96
- };
97
-
98
- const MockVueComputedComponent = {
99
- name: 'ComputedComponent',
100
- computed: {
101
- doubled() {
102
- return 2;
103
- },
104
- },
105
- };
106
-
107
- const MockVueMethodsComponent = {
108
- name: 'MethodsComponent',
109
- methods: {
110
- handleClick() {
111
- console.log('clicked');
112
- },
113
- },
114
- };
115
-
116
- describe('VueHMRAdapter - initialization', () => {
117
- it('should create adapter with correct name', () => {
118
- const adapter = new VueHMRAdapter();
119
-
120
- expect(adapter).toBeDefined();
121
- expect(adapter.name).toBe('vue');
122
- });
123
- });
124
-
125
- describe('VueHMRAdapter - canHandle', () => {
126
- it('should handle options component', () => {
127
- const adapter = new VueHMRAdapter();
128
-
129
- const result = adapter.canHandle(MockVueOptionsComponent);
130
- expect(result).toBe(true);
131
- });
132
-
133
- it('should handle setup component', () => {
134
- const adapter = new VueHMRAdapter();
135
-
136
- const result = adapter.canHandle(MockVueSetupComponent);
137
- expect(result).toBe(true);
138
- });
139
-
140
- it('should handle setup function', () => {
141
- const adapter = new VueHMRAdapter();
142
-
143
- const result = adapter.canHandle(MockVueSetupFunction);
144
- expect(result).toBe(true);
145
- });
146
-
147
- it('should handle SFC component', () => {
148
- const adapter = new VueHMRAdapter();
149
-
150
- const result = adapter.canHandle(MockVueSFCComponent);
151
- expect(result).toBe(true);
152
- });
153
-
154
- it('should handle computed component', () => {
155
- const adapter = new VueHMRAdapter();
156
-
157
- const result = adapter.canHandle(MockVueComputedComponent);
158
- expect(result).toBe(true);
159
- });
160
-
161
- it('should handle methods component', () => {
162
- const adapter = new VueHMRAdapter();
163
-
164
- const result = adapter.canHandle(MockVueMethodsComponent);
165
- expect(result).toBe(true);
166
- });
167
-
168
- it('should handle component with lifecycle hooks', () => {
169
- const adapter = new VueHMRAdapter();
170
-
171
- const componentWithHooks = {
172
- mounted() {
173
- console.log('mounted');
174
- },
175
- };
176
-
177
- const result = adapter.canHandle(componentWithHooks);
178
- expect(result).toBe(true);
179
- });
180
-
181
- it('should handle component with emits', () => {
182
- const adapter = new VueHMRAdapter();
183
-
184
- const componentWithEmits = {
185
- emits: ['update', 'change'],
186
- };
187
-
188
- const result = adapter.canHandle(componentWithEmits);
189
- expect(result).toBe(true);
190
- });
191
-
192
- it('should not handle non-Vue component', () => {
193
- const adapter = new VueHMRAdapter();
194
-
195
- expect(adapter.canHandle(null)).toBe(false);
196
- expect(adapter.canHandle(undefined)).toBe(false);
197
- expect(adapter.canHandle('string')).toBe(false);
198
- expect(adapter.canHandle(123)).toBe(false);
199
- expect(adapter.canHandle({})).toBe(false);
200
- expect(adapter.canHandle([])).toBe(false);
201
- });
202
- });
203
-
204
- describe('VueHMRAdapter - preserveState', () => {
205
- it('should return valid snapshot', () => {
206
- const adapter = new VueHMRAdapter();
207
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
208
-
209
- // Set up mock island attributes
210
- mockIsland.setAttribute('data-src', '/islands/TestComponent.vue');
211
- mockIsland.setAttribute('data-props', JSON.stringify({ count: 5 }));
212
-
213
- const snapshot = adapter.preserveState(mockIsland);
214
-
215
- // In test environment without DOM, preserveState returns null
216
- // This is expected behavior - the adapter gracefully handles missing DOM
217
- if (snapshot) {
218
- expect(snapshot.framework).toBe('vue');
219
- expect(typeof snapshot.timestamp).toBe('number');
220
- expect(snapshot.data).toBeDefined();
221
- } else {
222
- // Graceful degradation when DOM is not available
223
- expect(snapshot).toBeNull();
224
- }
225
- });
226
-
227
- it('should capture component name', () => {
228
- const adapter = new VueHMRAdapter();
229
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
230
-
231
- mockIsland.setAttribute('data-src', '/islands/Counter.vue');
232
- mockIsland.setAttribute('data-props', '{}');
233
-
234
- const snapshot = adapter.preserveState(mockIsland);
235
-
236
- // In test environment without DOM, preserveState returns null
237
- if (snapshot) {
238
- expect(snapshot.data.componentName).toBe('Counter');
239
- } else {
240
- // Expected in test environment
241
- expect(snapshot).toBeNull();
242
- }
243
- });
244
-
245
- it('should capture props', () => {
246
- const adapter = new VueHMRAdapter();
247
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
248
-
249
- const props = { count: 10, name: 'test' };
250
- mockIsland.setAttribute('data-src', '/islands/TestComponent.vue');
251
- mockIsland.setAttribute('data-props', JSON.stringify(props));
252
-
253
- const snapshot = adapter.preserveState(mockIsland);
254
-
255
- // In test environment without DOM, preserveState returns null
256
- if (snapshot) {
257
- expect(snapshot.data.capturedProps).toBeDefined();
258
- expect(snapshot.data.capturedProps).toEqual(props);
259
- } else {
260
- // Expected in test environment
261
- expect(snapshot).toBeNull();
262
- }
263
- });
264
-
265
- it('should handle missing props', () => {
266
- const adapter = new VueHMRAdapter();
267
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
268
-
269
- mockIsland.setAttribute('data-src', '/islands/TestComponent.vue');
270
- // No data-props attribute
271
-
272
- const snapshot = adapter.preserveState(mockIsland);
273
-
274
- // In test environment without DOM, preserveState returns null
275
- if (snapshot) {
276
- expect(snapshot.data.capturedProps).toBeDefined();
277
- expect(Object.keys(snapshot.data.capturedProps || {}).length).toBe(0);
278
- } else {
279
- // Expected in test environment
280
- expect(snapshot).toBeNull();
281
- }
282
- });
283
-
284
- it('should handle invalid JSON props', () => {
285
- const adapter = new VueHMRAdapter();
286
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
287
-
288
- mockIsland.setAttribute('data-src', '/islands/TestComponent.vue');
289
- mockIsland.setAttribute('data-props', 'invalid json');
290
-
291
- const snapshot = adapter.preserveState(mockIsland);
292
-
293
- // Should return null on error
294
- expect(snapshot).toBeNull();
295
- });
296
- });
297
-
298
- describe('VueHMRAdapter - restoreState', () => {
299
- it('should call base implementation', () => {
300
- const adapter = new VueHMRAdapter();
301
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
302
-
303
- const snapshot: StateSnapshot = {
304
- framework: 'vue',
305
- timestamp: Date.now(),
306
- data: {},
307
- dom: {
308
- scrollPosition: { x: 50, y: 100 },
309
- },
310
- };
311
-
312
- // Should not throw
313
- adapter.restoreState(mockIsland, snapshot);
314
-
315
- // Verify DOM state was restored
316
- expect(mockIsland.scrollLeft).toBe(50);
317
- expect(mockIsland.scrollTop).toBe(100);
318
- });
319
- });
320
-
321
- describe('VueHMRAdapter - handleError', () => {
322
- it('should add Vue-specific error info', () => {
323
- const adapter = new VueHMRAdapter();
324
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
325
-
326
- const error = new Error('Invalid reactive usage');
327
-
328
- // In test environment without DOM, handleError may fail
329
- // This is expected - the adapter requires DOM APIs
330
- try {
331
- adapter.handleError(mockIsland, error);
332
-
333
- // If it succeeds, verify error attributes were set
334
- expect(mockIsland.getAttribute('data-hmr-error')).toBe('true');
335
- expect(mockIsland.getAttribute('data-hmr-error-message')).toBe('Invalid reactive usage');
336
- } catch (e) {
337
- // Expected in test environment without DOM
338
- // The adapter gracefully handles missing DOM APIs
339
- expect((e as Error).message.includes('document is not defined')).toBe(true);
340
- }
341
- });
342
-
343
- it('should provide reactive hint', () => {
344
- const adapter = new VueHMRAdapter();
345
- const mockIsland = new MockHTMLElement() as unknown as HTMLElement;
346
-
347
- const error = new Error('ref must be accessed with .value');
348
-
349
- // The adapter should recognize reactive-related errors and provide helpful hints
350
- // This is tested indirectly through the error message
351
- try {
352
- adapter.handleError(mockIsland, error);
353
- } catch (e) {
354
- // Expected in test environment
355
- }
356
-
357
- // The actual hint is added to the error indicator element
358
- // which requires full DOM support to test properly
359
- });
360
- });
361
-
362
- describe('VueHMRAdapter - extractComponentName', () => {
363
- it('should extract from various paths', () => {
364
- const adapter = new VueHMRAdapter();
365
-
366
- // Access private method through type assertion for testing
367
- const extractName = (adapter as any).extractComponentName.bind(adapter);
368
-
369
- expect(extractName('/islands/Counter.vue')).toBe('Counter');
370
- expect(extractName('/islands/Button.tsx')).toBe('Button');
371
- expect(extractName('/src/components/Card.jsx')).toBe('Card');
372
- expect(extractName('/nested/path/Component.ts')).toBe('Component');
373
- expect(extractName('SimpleComponent.vue')).toBe('SimpleComponent');
374
- });
375
- });
376
-
377
- describe('VueHMRAdapter - generateComponentId', () => {
378
- it('should create valid ID', () => {
379
- const adapter = new VueHMRAdapter();
380
-
381
- // Access private method through type assertion for testing
382
- const generateId = (adapter as any).generateComponentId.bind(adapter);
383
-
384
- const id1 = generateId('/islands/Counter.vue');
385
- const id2 = generateId('/islands/Button.tsx');
386
- const id3 = generateId('/src/components/Card.jsx');
387
-
388
- // IDs should be valid (no special characters)
389
- expect(id1.match(/^[a-zA-Z0-9_]+$/) !== null).toBe(true);
390
- expect(id2.match(/^[a-zA-Z0-9_]+$/) !== null).toBe(true);
391
- expect(id3.match(/^[a-zA-Z0-9_]+$/) !== null).toBe(true);
392
-
393
- // Same path should generate same ID
394
- expect(generateId('/islands/Counter.vue')).toBe(id1);
395
- });
396
- });
397
-
398
- describe('VueHMRAdapter - singleton instance', () => {
399
- it('should export singleton', async () => {
400
- // Import the singleton
401
- const { vueAdapter } = await import('../adapters/vue-adapter.ts');
402
-
403
- expect(vueAdapter).toBeDefined();
404
- expect(vueAdapter.name).toBe('vue');
405
- expect(vueAdapter instanceof VueHMRAdapter).toBe(true);
406
- });
407
- });
@@ -1,96 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import {
3
- analyzeComponentFile,
4
- analyzeComponentContent,
5
- shouldHydrate,
6
- getComponentFramework,
7
- generateAnalysisSummary,
8
- } from '../../core/components/component-analyzer.ts';
9
-
10
- describe('Component Analyzer Integration', () => {
11
- it('should analyze real component files', () => {
12
- const svelteContent = `
13
- <script>
14
- import { onMount } from 'svelte';
15
- let count = 0;
16
- function increment() { count += 1; }
17
- onMount(() => { console.log('mounted'); });
18
- </script>
19
- <button on:click={increment}>{count}</button>
20
- `;
21
- const report = analyzeComponentContent('SvelteCounter.svelte', svelteContent, { logDecisions: false });
22
- expect(report.analysis.framework).toEqual('svelte');
23
- expect(report.analysis.hasScript).toEqual(true);
24
- expect(report.decision.shouldHydrate).toEqual(true);
25
- expect(report.metadata).toBeDefined();
26
- });
27
-
28
- it('should provide quick hydration check', () => {
29
- const noHydrateContent = `
30
- <div>
31
- <h1>Static Svelte Component</h1>
32
- <p>No JavaScript here</p>
33
- </div>
34
- `;
35
- const report = analyzeComponentContent('TestCounterNoHydrate.svelte', noHydrateContent);
36
- expect(report.decision.shouldHydrate).toEqual(false);
37
- });
38
-
39
- it('should detect component framework', () => {
40
- const vueContent = `
41
- <template>
42
- <div>{{ count }}</div>
43
- </template>
44
- <script setup>
45
- import { ref } from 'vue'
46
- const count = ref(0)
47
- </script>
48
- `;
49
- const report = analyzeComponentContent('TestCounter.vue', vueContent);
50
- expect(report.analysis.framework).toEqual('vue');
51
- });
52
-
53
- it('should analyze component content directly', () => {
54
- const vueContent = `
55
- <template>
56
- <div>Static content</div>
57
- </template>
58
- `;
59
-
60
- const report = analyzeComponentContent('test.vue', vueContent);
61
- expect(report.analysis.framework).toEqual('vue');
62
- expect(report.analysis.hasScript).toEqual(false);
63
- expect(report.decision.shouldHydrate).toEqual(false);
64
- });
65
-
66
- it('should handle analysis errors gracefully', async () => {
67
- const shouldHydrateResult = await shouldHydrate('non-existent.vue');
68
- expect(shouldHydrateResult).toEqual(true); // Defaults to hydrate on error
69
- });
70
- });
71
-
72
- describe('Analysis Summary Generation', () => {
73
- it('should generate summary statistics', () => {
74
- const mockReports = new Map();
75
-
76
- mockReports.set('comp1.vue', {
77
- analysis: { framework: 'vue', hasScript: true, hasHydrateFunction: true, recommendedStrategy: 'hydrate' },
78
- decision: { shouldHydrate: true, reason: 'test' },
79
- metadata: {},
80
- });
81
-
82
- mockReports.set('comp2.svelte', {
83
- analysis: { framework: 'svelte', hasScript: false, hasHydrateFunction: false, recommendedStrategy: 'ssr-only' },
84
- decision: { shouldHydrate: false, reason: 'test' },
85
- metadata: {},
86
- });
87
-
88
- const summary = generateAnalysisSummary(mockReports);
89
-
90
- expect(summary.total).toEqual(2);
91
- expect(summary.byFramework.vue).toEqual(1);
92
- expect(summary.byFramework.svelte).toEqual(1);
93
- expect(summary.byStrategy.hydrate).toEqual(1);
94
- expect(summary.byStrategy['ssr-only']).toEqual(1);
95
- });
96
- });