@useavalon/avalon 0.1.13 → 0.1.14
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/dist/mod.js +1 -0
- package/dist/src/build/integration-bundler-plugin.js +1 -0
- package/dist/src/build/integration-config.js +1 -0
- package/dist/src/build/integration-detection-plugin.js +1 -0
- package/dist/src/build/integration-resolver-plugin.js +1 -0
- package/dist/src/build/island-manifest.js +1 -0
- package/dist/src/build/island-types-generator.js +5 -0
- package/dist/src/build/mdx-island-transform.js +2 -0
- package/dist/src/build/mdx-plugin.js +1 -0
- package/dist/src/build/page-island-transform.js +3 -0
- package/dist/src/build/prop-extractors/index.js +1 -0
- package/dist/src/build/prop-extractors/lit.js +1 -0
- package/dist/src/build/prop-extractors/qwik.js +1 -0
- package/dist/src/build/prop-extractors/solid.js +1 -0
- package/dist/src/build/prop-extractors/svelte.js +1 -0
- package/dist/src/build/prop-extractors/vue.js +1 -0
- package/dist/src/build/sidecar-file-manager.js +1 -0
- package/dist/src/build/sidecar-renderer.js +6 -0
- package/dist/src/client/adapters/index.js +1 -0
- package/dist/src/client/components.js +1 -0
- package/dist/src/client/css-hmr-handler.js +1 -0
- package/dist/src/client/framework-adapter.js +13 -0
- package/dist/src/client/hmr-coordinator.js +1 -0
- package/dist/src/client/hmr-error-overlay.js +214 -0
- package/dist/src/client/main.js +39 -0
- package/dist/src/components/Image.js +1 -0
- package/dist/src/components/IslandErrorBoundary.js +1 -0
- package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
- package/dist/src/components/LayoutErrorBoundary.js +1 -0
- package/dist/src/components/PersistentIsland.js +1 -0
- package/dist/src/components/StreamingErrorBoundary.js +1 -0
- package/dist/src/components/StreamingLayout.js +29 -0
- package/dist/src/core/components/component-analyzer.js +1 -0
- package/dist/src/core/components/component-detection.js +5 -0
- package/dist/src/core/components/enhanced-framework-detector.js +1 -0
- package/dist/src/core/components/framework-registry.js +1 -0
- package/dist/src/core/content/mdx-processor.js +1 -0
- package/dist/src/core/integrations/index.js +1 -0
- package/dist/src/core/integrations/loader.js +1 -0
- package/dist/src/core/integrations/registry.js +1 -0
- package/dist/src/core/islands/island-persistence.js +1 -0
- package/dist/src/core/islands/island-state-serializer.js +1 -0
- package/dist/src/core/islands/persistent-island-context.js +1 -0
- package/dist/src/core/islands/use-persistent-state.js +1 -0
- package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
- package/dist/src/core/layout/layout-cache-manager.js +1 -0
- package/dist/src/core/layout/layout-composer.js +1 -0
- package/dist/src/core/layout/layout-data-loader.js +1 -0
- package/dist/src/core/layout/layout-discovery.js +1 -0
- package/dist/src/core/layout/layout-matcher.js +1 -0
- package/dist/src/core/layout/layout-types.js +1 -0
- package/dist/src/core/modules/framework-module-resolver.js +1 -0
- package/dist/src/islands/component-analysis.js +1 -0
- package/dist/src/islands/css-utils.js +17 -0
- package/dist/src/islands/discovery/index.js +1 -0
- package/dist/src/islands/discovery/registry.js +1 -0
- package/dist/src/islands/discovery/resolver.js +2 -0
- package/dist/src/islands/discovery/scanner.js +1 -0
- package/dist/src/islands/discovery/types.js +1 -0
- package/dist/src/islands/discovery/validator.js +18 -0
- package/dist/src/islands/discovery/watcher.js +1 -0
- package/dist/src/islands/framework-detection.js +1 -0
- package/dist/src/islands/integration-loader.js +1 -0
- package/dist/src/islands/island.js +1 -0
- package/dist/src/islands/render-cache.js +1 -0
- package/dist/src/islands/types.js +1 -0
- package/dist/src/islands/universal-css-collector.js +5 -0
- package/dist/src/islands/universal-head-collector.js +2 -0
- package/dist/src/layout-system.js +1 -0
- package/dist/src/middleware/discovery.js +1 -0
- package/dist/src/middleware/executor.js +1 -0
- package/dist/src/middleware/index.js +1 -0
- package/dist/src/middleware/types.js +1 -0
- package/dist/src/nitro/build-config.js +1 -0
- package/dist/src/nitro/config.js +1 -0
- package/dist/src/nitro/error-handler.js +198 -0
- package/dist/src/nitro/index.js +1 -0
- package/dist/src/nitro/island-manifest.js +2 -0
- package/dist/src/nitro/middleware-adapter.js +1 -0
- package/dist/src/nitro/renderer.js +183 -0
- package/dist/src/nitro/route-discovery.js +1 -0
- package/dist/src/nitro/types.js +1 -0
- package/dist/src/render/collect-css.js +3 -0
- package/dist/src/render/error-pages.js +48 -0
- package/dist/src/render/isolated-ssr-renderer.js +1 -0
- package/dist/src/render/ssr.js +90 -0
- package/dist/src/schemas/api.js +1 -0
- package/dist/src/schemas/core.js +1 -0
- package/dist/src/schemas/index.js +1 -0
- package/dist/src/schemas/layout.js +1 -0
- package/dist/src/schemas/routing/index.js +1 -0
- package/dist/src/schemas/routing.js +1 -0
- package/dist/src/types/as-island.js +1 -0
- package/dist/src/types/layout.js +1 -0
- package/dist/src/types/routing.js +1 -0
- package/dist/src/types/types.js +1 -0
- package/dist/src/utils/dev-logger.js +12 -0
- package/dist/src/utils/fs.js +1 -0
- package/dist/src/vite-plugin/auto-discover.js +1 -0
- package/dist/src/vite-plugin/config.js +1 -0
- package/dist/src/vite-plugin/errors.js +1 -0
- package/dist/src/vite-plugin/image-optimization.js +45 -0
- package/dist/src/vite-plugin/integration-activator.js +1 -0
- package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
- package/dist/src/vite-plugin/module-discovery.js +1 -0
- package/dist/src/vite-plugin/nitro-integration.js +42 -0
- package/dist/src/vite-plugin/plugin.js +1 -0
- package/dist/src/vite-plugin/types.js +1 -0
- package/dist/src/vite-plugin/validation.js +2 -0
- package/package.json +14 -20
- package/mod.ts +0 -302
- package/src/build/integration-bundler-plugin.ts +0 -116
- package/src/build/integration-config.ts +0 -168
- package/src/build/integration-detection-plugin.ts +0 -117
- package/src/build/integration-resolver-plugin.ts +0 -90
- package/src/build/island-manifest.ts +0 -269
- package/src/build/island-types-generator.ts +0 -476
- package/src/build/mdx-island-transform.ts +0 -464
- package/src/build/mdx-plugin.ts +0 -98
- package/src/build/page-island-transform.ts +0 -598
- package/src/build/prop-extractors/index.ts +0 -21
- package/src/build/prop-extractors/lit.ts +0 -140
- package/src/build/prop-extractors/qwik.ts +0 -16
- package/src/build/prop-extractors/solid.ts +0 -125
- package/src/build/prop-extractors/svelte.ts +0 -194
- package/src/build/prop-extractors/vue.ts +0 -111
- package/src/build/sidecar-file-manager.ts +0 -104
- package/src/build/sidecar-renderer.ts +0 -30
- package/src/client/adapters/index.ts +0 -21
- package/src/client/components.ts +0 -35
- package/src/client/css-hmr-handler.ts +0 -344
- package/src/client/framework-adapter.ts +0 -462
- package/src/client/hmr-coordinator.ts +0 -396
- package/src/client/hmr-error-overlay.js +0 -533
- package/src/client/main.js +0 -824
- package/src/components/Image.tsx +0 -123
- package/src/components/IslandErrorBoundary.tsx +0 -145
- package/src/components/LayoutDataErrorBoundary.tsx +0 -141
- package/src/components/LayoutErrorBoundary.tsx +0 -127
- package/src/components/PersistentIsland.tsx +0 -52
- package/src/components/StreamingErrorBoundary.tsx +0 -233
- package/src/components/StreamingLayout.tsx +0 -538
- package/src/core/components/component-analyzer.ts +0 -192
- package/src/core/components/component-detection.ts +0 -508
- package/src/core/components/enhanced-framework-detector.ts +0 -500
- package/src/core/components/framework-registry.ts +0 -563
- package/src/core/content/mdx-processor.ts +0 -46
- package/src/core/integrations/index.ts +0 -19
- package/src/core/integrations/loader.ts +0 -125
- package/src/core/integrations/registry.ts +0 -175
- package/src/core/islands/island-persistence.ts +0 -325
- package/src/core/islands/island-state-serializer.ts +0 -258
- package/src/core/islands/persistent-island-context.tsx +0 -80
- package/src/core/islands/use-persistent-state.ts +0 -68
- package/src/core/layout/enhanced-layout-resolver.ts +0 -322
- package/src/core/layout/layout-cache-manager.ts +0 -485
- package/src/core/layout/layout-composer.ts +0 -357
- package/src/core/layout/layout-data-loader.ts +0 -516
- package/src/core/layout/layout-discovery.ts +0 -243
- package/src/core/layout/layout-matcher.ts +0 -299
- package/src/core/layout/layout-types.ts +0 -110
- package/src/core/modules/framework-module-resolver.ts +0 -273
- package/src/islands/component-analysis.ts +0 -213
- package/src/islands/css-utils.ts +0 -565
- package/src/islands/discovery/index.ts +0 -80
- package/src/islands/discovery/registry.ts +0 -340
- package/src/islands/discovery/resolver.ts +0 -477
- package/src/islands/discovery/scanner.ts +0 -386
- package/src/islands/discovery/types.ts +0 -117
- package/src/islands/discovery/validator.ts +0 -544
- package/src/islands/discovery/watcher.ts +0 -368
- package/src/islands/framework-detection.ts +0 -428
- package/src/islands/integration-loader.ts +0 -490
- package/src/islands/island.tsx +0 -565
- package/src/islands/render-cache.ts +0 -550
- package/src/islands/types.ts +0 -80
- package/src/islands/universal-css-collector.ts +0 -157
- package/src/islands/universal-head-collector.ts +0 -137
- package/src/layout-system.ts +0 -218
- package/src/middleware/discovery.ts +0 -268
- package/src/middleware/executor.ts +0 -315
- package/src/middleware/index.ts +0 -76
- package/src/middleware/types.ts +0 -99
- package/src/nitro/build-config.ts +0 -576
- package/src/nitro/config.ts +0 -483
- package/src/nitro/error-handler.ts +0 -636
- package/src/nitro/index.ts +0 -173
- package/src/nitro/island-manifest.ts +0 -584
- package/src/nitro/middleware-adapter.ts +0 -260
- package/src/nitro/renderer.ts +0 -1471
- package/src/nitro/route-discovery.ts +0 -439
- package/src/nitro/types.ts +0 -321
- package/src/render/collect-css.ts +0 -198
- package/src/render/error-pages.ts +0 -79
- package/src/render/isolated-ssr-renderer.ts +0 -654
- package/src/render/ssr.ts +0 -1030
- package/src/schemas/api.ts +0 -30
- package/src/schemas/core.ts +0 -64
- package/src/schemas/index.ts +0 -212
- package/src/schemas/layout.ts +0 -279
- package/src/schemas/routing/index.ts +0 -38
- package/src/schemas/routing.ts +0 -376
- package/src/types/as-island.ts +0 -20
- package/src/types/layout.ts +0 -285
- package/src/types/routing.ts +0 -555
- package/src/types/types.ts +0 -5
- package/src/utils/dev-logger.ts +0 -299
- package/src/utils/fs.ts +0 -151
- package/src/vite-plugin/auto-discover.ts +0 -551
- package/src/vite-plugin/config.ts +0 -266
- package/src/vite-plugin/errors.ts +0 -127
- package/src/vite-plugin/image-optimization.ts +0 -156
- package/src/vite-plugin/integration-activator.ts +0 -126
- package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
- package/src/vite-plugin/module-discovery.ts +0 -189
- package/src/vite-plugin/nitro-integration.ts +0 -1354
- package/src/vite-plugin/plugin.ts +0 -403
- package/src/vite-plugin/types.ts +0 -327
- package/src/vite-plugin/validation.ts +0 -228
- /package/{src → dist/src}/client/types/framework-runtime.d.ts +0 -0
- /package/{src → dist/src}/client/types/vite-hmr.d.ts +0 -0
- /package/{src → dist/src}/client/types/vite-virtual-modules.d.ts +0 -0
- /package/{src → dist/src}/layout-system.d.ts +0 -0
- /package/{src → dist/src}/types/image.d.ts +0 -0
- /package/{src → dist/src}/types/index.d.ts +0 -0
- /package/{src → dist/src}/types/island-jsx.d.ts +0 -0
- /package/{src → dist/src}/types/island-prop.d.ts +0 -0
- /package/{src → dist/src}/types/mdx.d.ts +0 -0
- /package/{src → dist/src}/types/urlpattern.d.ts +0 -0
- /package/{src → dist/src}/types/vite-env.d.ts +0 -0
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/** Header comment placed at the top of every generated sidecar file. */
|
|
2
|
-
export const SIDECAR_HEADER = "// Auto-generated by avalon — do not edit";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Render the full content of a sidecar declaration file.
|
|
6
|
-
*
|
|
7
|
-
* Pure function: takes a props type string (e.g. `"{ count: number }"` or
|
|
8
|
-
* `"Record<string, unknown>"`) and returns the complete file content.
|
|
9
|
-
*
|
|
10
|
-
* The `island` prop is always included so the component can be used with
|
|
11
|
-
* `<Component island={{ condition: 'on:interaction' }} />` in page files.
|
|
12
|
-
* The Vite page-island-transform strips it at build time.
|
|
13
|
-
*
|
|
14
|
-
* The output follows this exact template:
|
|
15
|
-
* ```
|
|
16
|
-
* // Auto-generated by avalon — do not edit
|
|
17
|
-
* import type { ComponentType } from 'preact';
|
|
18
|
-
* import type { IslandDirective } from '@useavalon/avalon';
|
|
19
|
-
* declare const component: ComponentType<PROPS & { island?: IslandDirective }>;
|
|
20
|
-
* export default component;
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export function renderSidecarContent(propsType: string): string {
|
|
24
|
-
return `${SIDECAR_HEADER}
|
|
25
|
-
import type { ComponentType } from 'preact';
|
|
26
|
-
import type { IslandDirective } from '@useavalon/avalon';
|
|
27
|
-
declare const component: ComponentType<${propsType} & { island?: IslandDirective }>;
|
|
28
|
-
export default component;
|
|
29
|
-
`;
|
|
30
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Framework HMR Adapters
|
|
3
|
-
*
|
|
4
|
-
* HMR adapters have been moved to their respective integration packages:
|
|
5
|
-
* - @useavalon/react/client/hmr
|
|
6
|
-
* - @useavalon/preact/client/hmr
|
|
7
|
-
* - @useavalon/vue/client/hmr
|
|
8
|
-
* - @useavalon/svelte/client/hmr
|
|
9
|
-
* - @useavalon/solid/client/hmr
|
|
10
|
-
* - @useavalon/lit/client/hmr
|
|
11
|
-
* - @useavalon/qwik/client/hmr
|
|
12
|
-
*
|
|
13
|
-
* This barrel re-exports from the base framework adapter for backward compatibility.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
BaseFrameworkAdapter,
|
|
18
|
-
AdapterRegistry,
|
|
19
|
-
type FrameworkHMRAdapter,
|
|
20
|
-
type StateSnapshot,
|
|
21
|
-
} from '../framework-adapter.ts';
|
package/src/client/components.ts
DELETED
|
@@ -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';
|
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CSS HMR Handler
|
|
3
|
-
*
|
|
4
|
-
* Handles Hot Module Replacement for CSS files including:
|
|
5
|
-
* - Global CSS files
|
|
6
|
-
* - CSS modules
|
|
7
|
-
* - Component-scoped styles (Svelte, Vue)
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/// <reference lib="dom" />
|
|
11
|
-
/// <reference lib="dom.iterable" />
|
|
12
|
-
|
|
13
|
-
import type { Update } from './hmr-coordinator.ts';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* CSS update types
|
|
17
|
-
*/
|
|
18
|
-
export type CSSUpdateType = 'global' | 'module' | 'scoped';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* CSS update information
|
|
22
|
-
*/
|
|
23
|
-
export interface CSSUpdateInfo {
|
|
24
|
-
type: CSSUpdateType;
|
|
25
|
-
path: string;
|
|
26
|
-
timestamp: number;
|
|
27
|
-
affectedComponents?: string[];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* CSS HMR Handler class
|
|
32
|
-
* Manages CSS hot updates without page reload
|
|
33
|
-
*/
|
|
34
|
-
export class CSSHMRHandler {
|
|
35
|
-
private cssModuleMap: Map<string, Set<HTMLElement>> = new Map();
|
|
36
|
-
private styleElementMap: Map<string, HTMLStyleElement> = new Map();
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Handle CSS update from Vite HMR
|
|
40
|
-
*/
|
|
41
|
-
handleCSSUpdate(update: Update): void {
|
|
42
|
-
const updateInfo = this.classifyCSSUpdate(update);
|
|
43
|
-
|
|
44
|
-
switch (updateInfo.type) {
|
|
45
|
-
case 'global':
|
|
46
|
-
this.handleGlobalCSSUpdate(updateInfo);
|
|
47
|
-
break;
|
|
48
|
-
case 'module':
|
|
49
|
-
this.handleCSSModuleUpdate(updateInfo);
|
|
50
|
-
break;
|
|
51
|
-
case 'scoped':
|
|
52
|
-
this.handleScopedCSSUpdate(updateInfo);
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Classify the type of CSS update
|
|
59
|
-
*/
|
|
60
|
-
private classifyCSSUpdate(update: Update): CSSUpdateInfo {
|
|
61
|
-
const path = update.path || update.acceptedPath;
|
|
62
|
-
|
|
63
|
-
// Check if it's a CSS module
|
|
64
|
-
if (path.includes('.module.css') || path.includes('.module.scss')) {
|
|
65
|
-
return {
|
|
66
|
-
type: 'module',
|
|
67
|
-
path,
|
|
68
|
-
timestamp: update.timestamp,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Check if it's a scoped style (Svelte or Vue)
|
|
73
|
-
if (path.includes('.svelte') || path.includes('.vue')) {
|
|
74
|
-
return {
|
|
75
|
-
type: 'scoped',
|
|
76
|
-
path,
|
|
77
|
-
timestamp: update.timestamp,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Default to global CSS
|
|
82
|
-
return {
|
|
83
|
-
type: 'global',
|
|
84
|
-
path,
|
|
85
|
-
timestamp: update.timestamp,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Handle global CSS file update
|
|
91
|
-
* Injects updated styles without page reload
|
|
92
|
-
*/
|
|
93
|
-
private handleGlobalCSSUpdate(info: CSSUpdateInfo): void {
|
|
94
|
-
try {
|
|
95
|
-
// Find existing style element for this CSS file
|
|
96
|
-
const existingStyle = this.styleElementMap.get(info.path);
|
|
97
|
-
|
|
98
|
-
if (existingStyle) {
|
|
99
|
-
// Remove old style element
|
|
100
|
-
existingStyle.remove();
|
|
101
|
-
this.styleElementMap.delete(info.path);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Vite automatically injects the updated CSS via its HMR mechanism
|
|
105
|
-
// We just need to ensure old styles are removed
|
|
106
|
-
// The new styles will be injected by Vite's CSS handling
|
|
107
|
-
|
|
108
|
-
// Find the newly injected style element
|
|
109
|
-
// Vite adds a data-vite-dev-id attribute to style elements
|
|
110
|
-
const newStyle = document.querySelector<HTMLStyleElement>(
|
|
111
|
-
`style[data-vite-dev-id*="${this.getFileId(info.path)}"]`,
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
if (newStyle) {
|
|
115
|
-
this.styleElementMap.set(info.path, newStyle);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Dispatch event for feedback
|
|
119
|
-
this.dispatchCSSUpdateEvent(info, true);
|
|
120
|
-
} catch (error) {
|
|
121
|
-
console.error(`Failed to update global CSS: ${info.path}`, error);
|
|
122
|
-
this.dispatchCSSUpdateEvent(info, false, error as Error);
|
|
123
|
-
throw error;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Handle CSS module update
|
|
129
|
-
* Re-renders components using the updated CSS module
|
|
130
|
-
*/
|
|
131
|
-
private handleCSSModuleUpdate(info: CSSUpdateInfo): void {
|
|
132
|
-
try {
|
|
133
|
-
const affectedIslands = this.findIslandsUsingCSSModule(info.path);
|
|
134
|
-
|
|
135
|
-
if (affectedIslands.length === 0) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
for (const island of affectedIslands) {
|
|
140
|
-
this.triggerIslandRerender(island, info);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
this.dispatchCSSUpdateEvent(info, true);
|
|
144
|
-
} catch (error) {
|
|
145
|
-
console.error(`[HMR] Failed to update CSS module: ${info.path}`, error);
|
|
146
|
-
this.dispatchCSSUpdateEvent(info, false, error as Error);
|
|
147
|
-
throw error;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Handle scoped CSS update (Svelte/Vue)
|
|
153
|
-
* Updates only the affected component's styles
|
|
154
|
-
*/
|
|
155
|
-
private handleScopedCSSUpdate(info: CSSUpdateInfo): void {
|
|
156
|
-
try {
|
|
157
|
-
const affectedIslands = this.findIslandsUsingComponent(info.path);
|
|
158
|
-
|
|
159
|
-
if (affectedIslands.length === 0) {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
this.dispatchCSSUpdateEvent(info, true);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error(`[HMR] Failed to update scoped CSS: ${info.path}`, error);
|
|
166
|
-
this.dispatchCSSUpdateEvent(info, false, error as Error);
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Find islands that use a specific CSS module
|
|
173
|
-
*/
|
|
174
|
-
private findIslandsUsingCSSModule(cssPath: string): HTMLElement[] {
|
|
175
|
-
const islands: HTMLElement[] = [];
|
|
176
|
-
const normalizedPath = this.normalizePath(cssPath);
|
|
177
|
-
|
|
178
|
-
// Check cached mapping first
|
|
179
|
-
const cached = this.cssModuleMap.get(normalizedPath);
|
|
180
|
-
if (cached) {
|
|
181
|
-
return Array.from(cached);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Find all islands
|
|
185
|
-
const allIslands = document.querySelectorAll<HTMLElement>('[data-src]');
|
|
186
|
-
|
|
187
|
-
for (const island of allIslands) {
|
|
188
|
-
const src = island.getAttribute('data-src');
|
|
189
|
-
if (!src) continue;
|
|
190
|
-
|
|
191
|
-
// Check if the island's component likely imports this CSS module
|
|
192
|
-
// This is a heuristic - we look for islands in the same directory
|
|
193
|
-
const componentDir = this.getDirectory(src);
|
|
194
|
-
const cssDir = this.getDirectory(cssPath);
|
|
195
|
-
|
|
196
|
-
if (componentDir === cssDir) {
|
|
197
|
-
islands.push(island);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Cache the mapping
|
|
202
|
-
if (islands.length > 0) {
|
|
203
|
-
this.cssModuleMap.set(normalizedPath, new Set(islands));
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return islands;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Find islands using a specific component file
|
|
211
|
-
*/
|
|
212
|
-
private findIslandsUsingComponent(componentPath: string): HTMLElement[] {
|
|
213
|
-
const islands: HTMLElement[] = [];
|
|
214
|
-
const normalizedPath = this.normalizePath(componentPath);
|
|
215
|
-
|
|
216
|
-
const allIslands = document.querySelectorAll<HTMLElement>('[data-src]');
|
|
217
|
-
|
|
218
|
-
for (const island of allIslands) {
|
|
219
|
-
const src = island.getAttribute('data-src');
|
|
220
|
-
if (!src) continue;
|
|
221
|
-
|
|
222
|
-
const normalizedSrc = this.normalizePath(src);
|
|
223
|
-
|
|
224
|
-
if (normalizedSrc === normalizedPath || normalizedSrc.includes(normalizedPath)) {
|
|
225
|
-
islands.push(island);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return islands;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Trigger re-render of an island to apply new CSS module classes
|
|
234
|
-
*/
|
|
235
|
-
private triggerIslandRerender(island: HTMLElement, info: CSSUpdateInfo): void {
|
|
236
|
-
// Dispatch event to trigger island re-render
|
|
237
|
-
// The HMR coordinator will handle the actual re-render
|
|
238
|
-
island.dispatchEvent(
|
|
239
|
-
new CustomEvent('css-module-update', {
|
|
240
|
-
detail: {
|
|
241
|
-
cssPath: info.path,
|
|
242
|
-
timestamp: info.timestamp,
|
|
243
|
-
},
|
|
244
|
-
bubbles: true,
|
|
245
|
-
}),
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
// Also trigger a standard HMR update event
|
|
249
|
-
// This will be picked up by the HMR coordinator
|
|
250
|
-
const src = island.getAttribute('data-src');
|
|
251
|
-
if (src) {
|
|
252
|
-
island.dispatchEvent(
|
|
253
|
-
new CustomEvent('hmr-update-required', {
|
|
254
|
-
detail: {
|
|
255
|
-
src,
|
|
256
|
-
reason: 'css-module-update',
|
|
257
|
-
cssPath: info.path,
|
|
258
|
-
},
|
|
259
|
-
bubbles: true,
|
|
260
|
-
}),
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Dispatch CSS update event for feedback
|
|
267
|
-
*/
|
|
268
|
-
private dispatchCSSUpdateEvent(info: CSSUpdateInfo, success: boolean, error?: Error): void {
|
|
269
|
-
const event = new CustomEvent('css-hmr-update', {
|
|
270
|
-
detail: {
|
|
271
|
-
type: info.type,
|
|
272
|
-
path: info.path,
|
|
273
|
-
timestamp: info.timestamp,
|
|
274
|
-
success,
|
|
275
|
-
error: error?.message,
|
|
276
|
-
},
|
|
277
|
-
bubbles: true,
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
document.dispatchEvent(event);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Normalize a file path for comparison
|
|
285
|
-
*/
|
|
286
|
-
private normalizePath(path: string): string {
|
|
287
|
-
return path.replace(/\\/g, '/').replace(/^\//, '').replace(/\?.*$/, '').replace(/#.*$/, '');
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Get directory from a file path
|
|
292
|
-
*/
|
|
293
|
-
private getDirectory(path: string): string {
|
|
294
|
-
const normalized = this.normalizePath(path);
|
|
295
|
-
const lastSlash = normalized.lastIndexOf('/');
|
|
296
|
-
return lastSlash >= 0 ? normalized.substring(0, lastSlash) : '';
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Get file ID from path (for Vite's data-vite-dev-id)
|
|
301
|
-
*/
|
|
302
|
-
private getFileId(path: string): string {
|
|
303
|
-
const normalized = this.normalizePath(path);
|
|
304
|
-
// Vite uses the file path as the ID
|
|
305
|
-
return normalized;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Clear cached mappings
|
|
310
|
-
*/
|
|
311
|
-
clearCache(): void {
|
|
312
|
-
this.cssModuleMap.clear();
|
|
313
|
-
this.styleElementMap.clear();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Register an island as using a CSS module
|
|
318
|
-
* Useful for explicit tracking
|
|
319
|
-
*/
|
|
320
|
-
registerCSSModuleUsage(cssPath: string, island: HTMLElement): void {
|
|
321
|
-
const normalized = this.normalizePath(cssPath);
|
|
322
|
-
|
|
323
|
-
if (!this.cssModuleMap.has(normalized)) {
|
|
324
|
-
this.cssModuleMap.set(normalized, new Set());
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
this.cssModuleMap.get(normalized)!.add(island);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Global CSS HMR handler instance
|
|
333
|
-
*/
|
|
334
|
-
let cssHandlerInstance: CSSHMRHandler | null = null;
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Get or create the global CSS HMR handler instance
|
|
338
|
-
*/
|
|
339
|
-
export function getCSSHMRHandler(): CSSHMRHandler {
|
|
340
|
-
if (!cssHandlerInstance) {
|
|
341
|
-
cssHandlerInstance = new CSSHMRHandler();
|
|
342
|
-
}
|
|
343
|
-
return cssHandlerInstance;
|
|
344
|
-
}
|