@useavalon/avalon 0.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/README.md +54 -0
- package/mod.ts +301 -0
- package/package.json +85 -0
- package/src/build/README.md +310 -0
- package/src/build/integration-bundler-plugin.ts +116 -0
- package/src/build/integration-config.ts +168 -0
- package/src/build/integration-detection-plugin.ts +117 -0
- package/src/build/integration-resolver-plugin.ts +90 -0
- package/src/build/island-manifest.ts +269 -0
- package/src/build/island-types-generator.ts +476 -0
- package/src/build/mdx-island-transform.ts +464 -0
- package/src/build/mdx-plugin.ts +98 -0
- package/src/build/page-island-transform.ts +598 -0
- package/src/build/prop-extractors/index.ts +21 -0
- package/src/build/prop-extractors/lit.ts +140 -0
- package/src/build/prop-extractors/qwik.ts +16 -0
- package/src/build/prop-extractors/solid.ts +125 -0
- package/src/build/prop-extractors/svelte.ts +194 -0
- package/src/build/prop-extractors/vue.ts +111 -0
- package/src/build/sidecar-file-manager.ts +104 -0
- package/src/build/sidecar-renderer.ts +30 -0
- package/src/client/adapters/index.ts +13 -0
- package/src/client/adapters/lit-adapter.ts +654 -0
- package/src/client/adapters/preact-adapter.ts +331 -0
- package/src/client/adapters/qwik-adapter.ts +345 -0
- package/src/client/adapters/react-adapter.ts +353 -0
- package/src/client/adapters/solid-adapter.ts +451 -0
- package/src/client/adapters/svelte-adapter.ts +524 -0
- package/src/client/adapters/vue-adapter.ts +467 -0
- package/src/client/components.ts +35 -0
- package/src/client/css-hmr-handler.ts +344 -0
- package/src/client/framework-adapter.ts +462 -0
- package/src/client/hmr-coordinator.ts +396 -0
- package/src/client/hmr-error-overlay.js +533 -0
- package/src/client/main.js +816 -0
- package/src/client/tests/css-hmr-handler.test.ts +360 -0
- package/src/client/tests/framework-adapter.test.ts +519 -0
- package/src/client/tests/hmr-coordinator.test.ts +176 -0
- package/src/client/tests/hydration-option-parsing.test.ts +107 -0
- package/src/client/tests/lit-adapter.test.ts +427 -0
- package/src/client/tests/preact-adapter.test.ts +353 -0
- package/src/client/tests/qwik-adapter.test.ts +343 -0
- package/src/client/tests/react-adapter.test.ts +317 -0
- package/src/client/tests/solid-adapter.test.ts +396 -0
- package/src/client/tests/svelte-adapter.test.ts +387 -0
- package/src/client/tests/vue-adapter.test.ts +407 -0
- package/src/client/types/framework-runtime.d.ts +68 -0
- package/src/client/types/vite-hmr.d.ts +46 -0
- package/src/client/types/vite-virtual-modules.d.ts +60 -0
- package/src/components/Image.tsx +123 -0
- package/src/components/IslandErrorBoundary.tsx +145 -0
- package/src/components/LayoutDataErrorBoundary.tsx +141 -0
- package/src/components/LayoutErrorBoundary.tsx +127 -0
- package/src/components/PersistentIsland.tsx +52 -0
- package/src/components/StreamingErrorBoundary.tsx +233 -0
- package/src/components/StreamingLayout.tsx +538 -0
- package/src/components/tests/component-analyzer.test.ts +96 -0
- package/src/components/tests/component-detection.test.ts +347 -0
- package/src/components/tests/persistent-islands.test.ts +398 -0
- package/src/core/components/component-analyzer.ts +192 -0
- package/src/core/components/component-detection.ts +508 -0
- package/src/core/components/enhanced-framework-detector.ts +500 -0
- package/src/core/components/framework-registry.ts +563 -0
- package/src/core/components/tests/enhanced-framework-detector.test.ts +577 -0
- package/src/core/components/tests/framework-registry.test.ts +465 -0
- package/src/core/content/mdx-processor.ts +46 -0
- package/src/core/integrations/README.md +282 -0
- package/src/core/integrations/index.ts +19 -0
- package/src/core/integrations/loader.ts +125 -0
- package/src/core/integrations/registry.ts +195 -0
- package/src/core/islands/island-persistence.ts +325 -0
- package/src/core/islands/island-state-serializer.ts +258 -0
- package/src/core/islands/persistent-island-context.tsx +80 -0
- package/src/core/islands/use-persistent-state.ts +68 -0
- package/src/core/layout/enhanced-layout-resolver.ts +322 -0
- package/src/core/layout/layout-cache-manager.ts +485 -0
- package/src/core/layout/layout-composer.ts +357 -0
- package/src/core/layout/layout-data-loader.ts +516 -0
- package/src/core/layout/layout-discovery.ts +243 -0
- package/src/core/layout/layout-matcher.ts +299 -0
- package/src/core/layout/layout-types.ts +110 -0
- package/src/core/layout/tests/enhanced-layout-resolver.test.ts +477 -0
- package/src/core/layout/tests/layout-cache-optimization.test.ts +149 -0
- package/src/core/layout/tests/layout-composer.test.ts +486 -0
- package/src/core/layout/tests/layout-data-loader.test.ts +443 -0
- package/src/core/layout/tests/layout-discovery.test.ts +253 -0
- package/src/core/layout/tests/layout-matcher.test.ts +480 -0
- package/src/core/modules/framework-module-resolver.ts +273 -0
- package/src/core/modules/tests/framework-module-resolver.test.ts +263 -0
- package/src/core/modules/tests/module-resolution-integration.test.ts +117 -0
- package/src/islands/component-analysis.ts +213 -0
- package/src/islands/css-utils.ts +565 -0
- package/src/islands/discovery/index.ts +80 -0
- package/src/islands/discovery/registry.ts +340 -0
- package/src/islands/discovery/resolver.ts +477 -0
- package/src/islands/discovery/scanner.ts +386 -0
- package/src/islands/discovery/tests/island-discovery.test.ts +881 -0
- package/src/islands/discovery/types.ts +117 -0
- package/src/islands/discovery/validator.ts +544 -0
- package/src/islands/discovery/watcher.ts +368 -0
- package/src/islands/framework-detection.ts +428 -0
- package/src/islands/integration-loader.ts +490 -0
- package/src/islands/island.tsx +565 -0
- package/src/islands/render-cache.ts +550 -0
- package/src/islands/types.ts +80 -0
- package/src/islands/universal-css-collector.ts +157 -0
- package/src/islands/universal-head-collector.ts +137 -0
- package/src/layout-system.d.ts +592 -0
- package/src/layout-system.ts +218 -0
- package/src/middleware/__tests__/discovery.test.ts +107 -0
- package/src/middleware/discovery.ts +268 -0
- package/src/middleware/executor.ts +315 -0
- package/src/middleware/index.ts +76 -0
- package/src/middleware/types.ts +99 -0
- package/src/nitro/build-config.ts +576 -0
- package/src/nitro/config.ts +483 -0
- package/src/nitro/error-handler.ts +636 -0
- package/src/nitro/index.ts +173 -0
- package/src/nitro/island-manifest.ts +584 -0
- package/src/nitro/middleware-adapter.ts +260 -0
- package/src/nitro/renderer.ts +1458 -0
- package/src/nitro/route-discovery.ts +439 -0
- package/src/nitro/types.ts +321 -0
- package/src/render/collect-css.ts +198 -0
- package/src/render/error-pages.ts +79 -0
- package/src/render/isolated-ssr-renderer.ts +654 -0
- package/src/render/ssr.ts +1030 -0
- package/src/schemas/api.ts +30 -0
- package/src/schemas/core.ts +64 -0
- package/src/schemas/index.ts +212 -0
- package/src/schemas/layout.ts +279 -0
- package/src/schemas/routing/index.ts +38 -0
- package/src/schemas/routing.ts +376 -0
- package/src/types/as-island.ts +20 -0
- package/src/types/image.d.ts +106 -0
- package/src/types/index.d.ts +22 -0
- package/src/types/island-jsx.d.ts +33 -0
- package/src/types/island-prop.d.ts +20 -0
- package/src/types/layout.ts +285 -0
- package/src/types/mdx.d.ts +6 -0
- package/src/types/routing.ts +555 -0
- package/src/types/tests/layout-types.test.ts +197 -0
- package/src/types/types.ts +5 -0
- package/src/types/urlpattern.d.ts +49 -0
- package/src/types/vite-env.d.ts +11 -0
- package/src/utils/dev-logger.ts +299 -0
- package/src/utils/fs.ts +151 -0
- package/src/vite-plugin/auto-discover.ts +551 -0
- package/src/vite-plugin/config.ts +266 -0
- package/src/vite-plugin/errors.ts +127 -0
- package/src/vite-plugin/image-optimization.ts +151 -0
- package/src/vite-plugin/integration-activator.ts +126 -0
- package/src/vite-plugin/island-sidecar-plugin.ts +176 -0
- package/src/vite-plugin/module-discovery.ts +189 -0
- package/src/vite-plugin/nitro-integration.ts +1334 -0
- package/src/vite-plugin/plugin.ts +329 -0
- package/src/vite-plugin/tests/image-optimization.test.ts +54 -0
- package/src/vite-plugin/types.ts +327 -0
- package/src/vite-plugin/validation.ts +228 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for CSS HMR Handler
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect } from 'vitest';
|
|
6
|
+
import { CSSHMRHandler, getCSSHMRHandler } from '../css-hmr-handler.ts';
|
|
7
|
+
import type { Update } from '../hmr-coordinator.ts';
|
|
8
|
+
|
|
9
|
+
// Mock DOM environment for testing
|
|
10
|
+
class MockDocument {
|
|
11
|
+
private listeners: Map<string, Array<(event: Event) => void>> = new Map();
|
|
12
|
+
private elements: MockHTMLElement[] = [];
|
|
13
|
+
head: { appendChild: (el: any) => void; querySelector: (selector: string) => any } = {
|
|
14
|
+
appendChild: () => {},
|
|
15
|
+
querySelector: () => null,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
addEventListener(event: string, callback: (event: Event) => void): void {
|
|
19
|
+
if (!this.listeners.has(event)) {
|
|
20
|
+
this.listeners.set(event, []);
|
|
21
|
+
}
|
|
22
|
+
this.listeners.get(event)!.push(callback);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
dispatchEvent(event: Event): void {
|
|
26
|
+
const callbacks = this.listeners.get(event.type) || [];
|
|
27
|
+
for (const callback of callbacks) {
|
|
28
|
+
callback(event);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
querySelector<T extends Element>(selector: string): T | null {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
querySelectorAll<T extends Element>(selector: string): T[] {
|
|
37
|
+
const filtered = this.elements.filter(el => {
|
|
38
|
+
if (selector === '[data-src]') {
|
|
39
|
+
return el.hasAttribute('data-src');
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
});
|
|
43
|
+
return filtered as unknown as T[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
addElement(element: MockHTMLElement): void {
|
|
47
|
+
this.elements.push(element);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
clearElements(): void {
|
|
51
|
+
this.elements = [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
clearListeners(): void {
|
|
55
|
+
this.listeners.clear();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class MockHTMLElement {
|
|
60
|
+
private attributes: Map<string, string> = new Map();
|
|
61
|
+
private listeners: Map<string, Array<(event: Event) => void>> = new Map();
|
|
62
|
+
|
|
63
|
+
getAttribute(name: string): string | null {
|
|
64
|
+
return this.attributes.get(name) || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
setAttribute(name: string, value: string): void {
|
|
68
|
+
this.attributes.set(name, value);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
removeAttribute(name: string): void {
|
|
72
|
+
this.attributes.delete(name);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
hasAttribute(name: string): boolean {
|
|
76
|
+
return this.attributes.has(name);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
addEventListener(event: string, callback: (event: Event) => void): void {
|
|
80
|
+
if (!this.listeners.has(event)) {
|
|
81
|
+
this.listeners.set(event, []);
|
|
82
|
+
}
|
|
83
|
+
this.listeners.get(event)!.push(callback);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
dispatchEvent(event: Event): void {
|
|
87
|
+
const callbacks = this.listeners.get(event.type) || [];
|
|
88
|
+
for (const callback of callbacks) {
|
|
89
|
+
callback(event);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
class MockCustomEvent extends Event {
|
|
95
|
+
detail: any;
|
|
96
|
+
|
|
97
|
+
constructor(type: string, options?: { detail?: any; bubbles?: boolean }) {
|
|
98
|
+
super(type, options);
|
|
99
|
+
this.detail = options?.detail;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Setup mock global document
|
|
104
|
+
const mockDocument = new MockDocument();
|
|
105
|
+
(globalThis as any).document = mockDocument;
|
|
106
|
+
(globalThis as any).CustomEvent = MockCustomEvent;
|
|
107
|
+
|
|
108
|
+
describe('CSSHMRHandler - Global CSS Updates', () => {
|
|
109
|
+
it('should handle global CSS update', async () => {
|
|
110
|
+
mockDocument.clearListeners();
|
|
111
|
+
|
|
112
|
+
const handler = new CSSHMRHandler();
|
|
113
|
+
const update: Update = {
|
|
114
|
+
type: 'css-update',
|
|
115
|
+
path: '/src/styles/global.css',
|
|
116
|
+
acceptedPath: '/src/styles/global.css',
|
|
117
|
+
timestamp: Date.now(),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
let eventFired = false;
|
|
121
|
+
let eventDetail: any = null;
|
|
122
|
+
mockDocument.addEventListener('css-hmr-update', (e: Event) => {
|
|
123
|
+
const customEvent = e as MockCustomEvent;
|
|
124
|
+
eventFired = true;
|
|
125
|
+
eventDetail = customEvent.detail;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
await handler.handleCSSUpdate(update);
|
|
129
|
+
|
|
130
|
+
expect(eventFired).toBe(true);
|
|
131
|
+
expect(eventDetail.type).toBe('global');
|
|
132
|
+
expect(eventDetail.success).toBe(true);
|
|
133
|
+
handler.clearCache();
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('CSSHMRHandler - CSS Module Updates', () => {
|
|
138
|
+
it('should identify CSS module updates', async () => {
|
|
139
|
+
mockDocument.clearListeners();
|
|
140
|
+
mockDocument.clearElements();
|
|
141
|
+
|
|
142
|
+
// Add an island so the event fires
|
|
143
|
+
const mockIsland = new MockHTMLElement();
|
|
144
|
+
mockIsland.setAttribute('data-src', '/src/islands/TestComponent.tsx');
|
|
145
|
+
mockDocument.addElement(mockIsland);
|
|
146
|
+
|
|
147
|
+
const handler = new CSSHMRHandler();
|
|
148
|
+
const update: Update = {
|
|
149
|
+
type: 'css-update',
|
|
150
|
+
path: '/src/islands/TestComponent.module.css',
|
|
151
|
+
acceptedPath: '/src/islands/TestComponent.module.css',
|
|
152
|
+
timestamp: Date.now(),
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
let eventFired = false;
|
|
156
|
+
let eventDetail: any = null;
|
|
157
|
+
mockDocument.addEventListener('css-hmr-update', (e: Event) => {
|
|
158
|
+
const customEvent = e as MockCustomEvent;
|
|
159
|
+
eventFired = true;
|
|
160
|
+
eventDetail = customEvent.detail;
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
await handler.handleCSSUpdate(update);
|
|
164
|
+
|
|
165
|
+
expect(eventFired).toBe(true);
|
|
166
|
+
expect(eventDetail.type).toBe('module');
|
|
167
|
+
handler.clearCache();
|
|
168
|
+
mockDocument.clearElements();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should find islands using CSS module in same directory', async () => {
|
|
172
|
+
mockDocument.clearElements();
|
|
173
|
+
mockDocument.clearListeners();
|
|
174
|
+
|
|
175
|
+
const mockIsland = new MockHTMLElement();
|
|
176
|
+
mockIsland.setAttribute('data-src', '/src/islands/TestComponent.tsx');
|
|
177
|
+
mockIsland.setAttribute('data-framework', 'react');
|
|
178
|
+
mockIsland.setAttribute('data-hydrated', 'true');
|
|
179
|
+
mockDocument.addElement(mockIsland);
|
|
180
|
+
|
|
181
|
+
const handler = new CSSHMRHandler();
|
|
182
|
+
const update: Update = {
|
|
183
|
+
type: 'css-update',
|
|
184
|
+
path: '/src/islands/TestComponent.module.css',
|
|
185
|
+
acceptedPath: '/src/islands/TestComponent.module.css',
|
|
186
|
+
timestamp: Date.now(),
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
let rerenderEventFired = false;
|
|
190
|
+
mockIsland.addEventListener('hmr-update-required', (e: Event) => {
|
|
191
|
+
const customEvent = e as MockCustomEvent;
|
|
192
|
+
rerenderEventFired = true;
|
|
193
|
+
expect(customEvent.detail.reason).toBe('css-module-update');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
await handler.handleCSSUpdate(update);
|
|
197
|
+
|
|
198
|
+
expect(rerenderEventFired).toBe(true);
|
|
199
|
+
handler.clearCache();
|
|
200
|
+
mockDocument.clearElements();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('should handle CSS module with no affected islands', async () => {
|
|
204
|
+
mockDocument.clearElements();
|
|
205
|
+
|
|
206
|
+
const handler = new CSSHMRHandler();
|
|
207
|
+
const update: Update = {
|
|
208
|
+
type: 'css-update',
|
|
209
|
+
path: '/src/other/Unrelated.module.css',
|
|
210
|
+
acceptedPath: '/src/other/Unrelated.module.css',
|
|
211
|
+
timestamp: Date.now(),
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// Should not throw error
|
|
215
|
+
await handler.handleCSSUpdate(update);
|
|
216
|
+
handler.clearCache();
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
describe('CSSHMRHandler - Scoped CSS Updates', () => {
|
|
221
|
+
it('should identify scoped CSS updates for Svelte', async () => {
|
|
222
|
+
mockDocument.clearListeners();
|
|
223
|
+
mockDocument.clearElements();
|
|
224
|
+
|
|
225
|
+
// Add an island so the event fires
|
|
226
|
+
const mockIsland = new MockHTMLElement();
|
|
227
|
+
mockIsland.setAttribute('data-src', '/src/islands/TestComponent.svelte');
|
|
228
|
+
mockDocument.addElement(mockIsland);
|
|
229
|
+
|
|
230
|
+
const handler = new CSSHMRHandler();
|
|
231
|
+
const update: Update = {
|
|
232
|
+
type: 'css-update',
|
|
233
|
+
path: '/src/islands/TestComponent.svelte',
|
|
234
|
+
acceptedPath: '/src/islands/TestComponent.svelte',
|
|
235
|
+
timestamp: Date.now(),
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
let eventFired = false;
|
|
239
|
+
let eventDetail: any = null;
|
|
240
|
+
mockDocument.addEventListener('css-hmr-update', (e: Event) => {
|
|
241
|
+
const customEvent = e as MockCustomEvent;
|
|
242
|
+
eventFired = true;
|
|
243
|
+
eventDetail = customEvent.detail;
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
await handler.handleCSSUpdate(update);
|
|
247
|
+
|
|
248
|
+
expect(eventFired).toBe(true);
|
|
249
|
+
expect(eventDetail.type).toBe('scoped');
|
|
250
|
+
handler.clearCache();
|
|
251
|
+
mockDocument.clearElements();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should identify scoped CSS updates for Vue', async () => {
|
|
255
|
+
mockDocument.clearListeners();
|
|
256
|
+
mockDocument.clearElements();
|
|
257
|
+
|
|
258
|
+
// Add an island so the event fires
|
|
259
|
+
const mockIsland = new MockHTMLElement();
|
|
260
|
+
mockIsland.setAttribute('data-src', '/src/islands/TestComponent.vue');
|
|
261
|
+
mockDocument.addElement(mockIsland);
|
|
262
|
+
|
|
263
|
+
const handler = new CSSHMRHandler();
|
|
264
|
+
const update: Update = {
|
|
265
|
+
type: 'css-update',
|
|
266
|
+
path: '/src/islands/TestComponent.vue',
|
|
267
|
+
acceptedPath: '/src/islands/TestComponent.vue',
|
|
268
|
+
timestamp: Date.now(),
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
let eventFired = false;
|
|
272
|
+
let eventDetail: any = null;
|
|
273
|
+
mockDocument.addEventListener('css-hmr-update', (e: Event) => {
|
|
274
|
+
const customEvent = e as MockCustomEvent;
|
|
275
|
+
eventFired = true;
|
|
276
|
+
eventDetail = customEvent.detail;
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
await handler.handleCSSUpdate(update);
|
|
280
|
+
|
|
281
|
+
expect(eventFired).toBe(true);
|
|
282
|
+
expect(eventDetail.type).toBe('scoped');
|
|
283
|
+
handler.clearCache();
|
|
284
|
+
mockDocument.clearElements();
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe('CSSHMRHandler - CSS Module Registration', () => {
|
|
289
|
+
it('should register CSS module usage explicitly', async () => {
|
|
290
|
+
mockDocument.clearElements();
|
|
291
|
+
mockDocument.clearListeners();
|
|
292
|
+
|
|
293
|
+
const mockIsland = new MockHTMLElement();
|
|
294
|
+
mockIsland.setAttribute('data-src', '/src/islands/TestComponent.tsx');
|
|
295
|
+
mockDocument.addElement(mockIsland);
|
|
296
|
+
|
|
297
|
+
const handler = new CSSHMRHandler();
|
|
298
|
+
handler.registerCSSModuleUsage('/src/islands/Test.module.css', mockIsland as any);
|
|
299
|
+
|
|
300
|
+
const update: Update = {
|
|
301
|
+
type: 'css-update',
|
|
302
|
+
path: '/src/islands/Test.module.css',
|
|
303
|
+
acceptedPath: '/src/islands/Test.module.css',
|
|
304
|
+
timestamp: Date.now(),
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
let eventFired = false;
|
|
308
|
+
mockIsland.addEventListener('hmr-update-required', () => {
|
|
309
|
+
eventFired = true;
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
await handler.handleCSSUpdate(update);
|
|
313
|
+
|
|
314
|
+
expect(eventFired).toBe(true);
|
|
315
|
+
handler.clearCache();
|
|
316
|
+
mockDocument.clearElements();
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe('CSSHMRHandler - Cache Management', () => {
|
|
321
|
+
it('should clear cache', async () => {
|
|
322
|
+
mockDocument.clearElements();
|
|
323
|
+
|
|
324
|
+
const mockIsland = new MockHTMLElement();
|
|
325
|
+
mockIsland.setAttribute('data-src', '/src/islands/TestComponent.tsx');
|
|
326
|
+
mockDocument.addElement(mockIsland);
|
|
327
|
+
|
|
328
|
+
const handler = new CSSHMRHandler();
|
|
329
|
+
handler.registerCSSModuleUsage('/src/test.module.css', mockIsland as any);
|
|
330
|
+
handler.clearCache();
|
|
331
|
+
|
|
332
|
+
const update: Update = {
|
|
333
|
+
type: 'css-update',
|
|
334
|
+
path: '/src/test.module.css',
|
|
335
|
+
acceptedPath: '/src/test.module.css',
|
|
336
|
+
timestamp: Date.now(),
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
let eventFired = false;
|
|
340
|
+
mockIsland.addEventListener('hmr-update-required', () => {
|
|
341
|
+
eventFired = true;
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
await handler.handleCSSUpdate(update);
|
|
345
|
+
|
|
346
|
+
// Should not find the island after cache clear
|
|
347
|
+
expect(eventFired).toBe(false);
|
|
348
|
+
handler.clearCache();
|
|
349
|
+
mockDocument.clearElements();
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
describe('CSSHMRHandler - Singleton Instance', () => {
|
|
354
|
+
it('should return same instance from getCSSHMRHandler', () => {
|
|
355
|
+
const instance1 = getCSSHMRHandler();
|
|
356
|
+
const instance2 = getCSSHMRHandler();
|
|
357
|
+
|
|
358
|
+
expect(instance1).toBe(instance2);
|
|
359
|
+
});
|
|
360
|
+
});
|