@useavalon/avalon 0.1.11 → 0.1.13
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 -54
- package/mod.ts +302 -302
- package/package.json +49 -26
- package/src/build/integration-bundler-plugin.ts +116 -116
- package/src/build/integration-config.ts +168 -168
- package/src/build/integration-detection-plugin.ts +117 -117
- package/src/build/integration-resolver-plugin.ts +90 -90
- package/src/build/island-manifest.ts +269 -269
- package/src/build/island-types-generator.ts +476 -476
- package/src/build/mdx-island-transform.ts +464 -464
- package/src/build/mdx-plugin.ts +98 -98
- package/src/build/page-island-transform.ts +598 -598
- package/src/build/prop-extractors/index.ts +21 -21
- package/src/build/prop-extractors/lit.ts +140 -140
- package/src/build/prop-extractors/qwik.ts +16 -16
- package/src/build/prop-extractors/solid.ts +125 -125
- package/src/build/prop-extractors/svelte.ts +194 -194
- package/src/build/prop-extractors/vue.ts +111 -111
- package/src/build/sidecar-file-manager.ts +104 -104
- package/src/build/sidecar-renderer.ts +30 -30
- package/src/client/adapters/index.ts +21 -13
- package/src/client/components.ts +35 -35
- package/src/client/css-hmr-handler.ts +344 -344
- package/src/client/framework-adapter.ts +462 -462
- package/src/client/hmr-coordinator.ts +396 -396
- package/src/client/hmr-error-overlay.js +533 -533
- package/src/client/main.js +824 -816
- package/src/client/types/framework-runtime.d.ts +68 -68
- package/src/client/types/vite-hmr.d.ts +46 -46
- package/src/client/types/vite-virtual-modules.d.ts +70 -60
- package/src/components/Image.tsx +123 -123
- package/src/components/IslandErrorBoundary.tsx +145 -145
- package/src/components/LayoutDataErrorBoundary.tsx +141 -141
- package/src/components/LayoutErrorBoundary.tsx +127 -127
- package/src/components/PersistentIsland.tsx +52 -52
- package/src/components/StreamingErrorBoundary.tsx +233 -233
- package/src/components/StreamingLayout.tsx +538 -538
- package/src/core/components/component-analyzer.ts +192 -192
- package/src/core/components/component-detection.ts +508 -508
- package/src/core/components/enhanced-framework-detector.ts +500 -500
- package/src/core/components/framework-registry.ts +563 -563
- package/src/core/content/mdx-processor.ts +46 -46
- package/src/core/integrations/index.ts +19 -19
- package/src/core/integrations/loader.ts +125 -125
- package/src/core/integrations/registry.ts +175 -175
- package/src/core/islands/island-persistence.ts +325 -325
- package/src/core/islands/island-state-serializer.ts +258 -258
- package/src/core/islands/persistent-island-context.tsx +80 -80
- package/src/core/islands/use-persistent-state.ts +68 -68
- package/src/core/layout/enhanced-layout-resolver.ts +322 -322
- package/src/core/layout/layout-cache-manager.ts +485 -485
- package/src/core/layout/layout-composer.ts +357 -357
- package/src/core/layout/layout-data-loader.ts +516 -516
- package/src/core/layout/layout-discovery.ts +243 -243
- package/src/core/layout/layout-matcher.ts +299 -299
- package/src/core/layout/layout-types.ts +110 -110
- package/src/core/modules/framework-module-resolver.ts +273 -273
- package/src/islands/component-analysis.ts +213 -213
- package/src/islands/css-utils.ts +565 -565
- package/src/islands/discovery/index.ts +80 -80
- package/src/islands/discovery/registry.ts +340 -340
- package/src/islands/discovery/resolver.ts +477 -477
- package/src/islands/discovery/scanner.ts +386 -386
- package/src/islands/discovery/types.ts +117 -117
- package/src/islands/discovery/validator.ts +544 -544
- package/src/islands/discovery/watcher.ts +368 -368
- package/src/islands/framework-detection.ts +428 -428
- package/src/islands/integration-loader.ts +490 -490
- package/src/islands/island.tsx +565 -565
- package/src/islands/render-cache.ts +550 -550
- package/src/islands/types.ts +80 -80
- package/src/islands/universal-css-collector.ts +157 -157
- package/src/islands/universal-head-collector.ts +137 -137
- package/src/layout-system.d.ts +592 -592
- package/src/layout-system.ts +218 -218
- package/src/middleware/discovery.ts +268 -268
- package/src/middleware/executor.ts +315 -315
- package/src/middleware/index.ts +76 -76
- package/src/middleware/types.ts +99 -99
- package/src/nitro/build-config.ts +575 -575
- package/src/nitro/config.ts +483 -483
- package/src/nitro/error-handler.ts +636 -636
- package/src/nitro/index.ts +173 -173
- package/src/nitro/island-manifest.ts +584 -584
- package/src/nitro/middleware-adapter.ts +260 -260
- package/src/nitro/renderer.ts +1471 -1471
- package/src/nitro/route-discovery.ts +439 -439
- package/src/nitro/types.ts +321 -321
- package/src/render/collect-css.ts +198 -198
- package/src/render/error-pages.ts +79 -79
- package/src/render/isolated-ssr-renderer.ts +654 -654
- package/src/render/ssr.ts +1030 -1030
- package/src/schemas/api.ts +30 -30
- package/src/schemas/core.ts +64 -64
- package/src/schemas/index.ts +212 -212
- package/src/schemas/layout.ts +279 -279
- package/src/schemas/routing/index.ts +38 -38
- package/src/schemas/routing.ts +376 -376
- package/src/types/as-island.ts +20 -20
- package/src/types/image.d.ts +106 -106
- package/src/types/index.d.ts +22 -22
- package/src/types/island-jsx.d.ts +33 -33
- package/src/types/island-prop.d.ts +20 -20
- package/src/types/layout.ts +285 -285
- package/src/types/mdx.d.ts +6 -6
- package/src/types/routing.ts +555 -555
- package/src/types/types.ts +5 -5
- package/src/types/urlpattern.d.ts +49 -49
- package/src/types/vite-env.d.ts +11 -11
- package/src/utils/dev-logger.ts +299 -299
- package/src/utils/fs.ts +151 -151
- package/src/vite-plugin/auto-discover.ts +551 -551
- package/src/vite-plugin/config.ts +266 -266
- package/src/vite-plugin/errors.ts +127 -127
- package/src/vite-plugin/image-optimization.ts +156 -156
- package/src/vite-plugin/integration-activator.ts +126 -126
- package/src/vite-plugin/island-sidecar-plugin.ts +176 -176
- package/src/vite-plugin/module-discovery.ts +189 -189
- package/src/vite-plugin/nitro-integration.ts +1354 -1354
- package/src/vite-plugin/plugin.ts +403 -409
- package/src/vite-plugin/types.ts +327 -327
- package/src/vite-plugin/validation.ts +228 -228
- package/src/client/adapters/index.js +0 -12
- package/src/client/adapters/lit-adapter.js +0 -467
- package/src/client/adapters/lit-adapter.ts +0 -654
- package/src/client/adapters/preact-adapter.js +0 -223
- package/src/client/adapters/preact-adapter.ts +0 -331
- package/src/client/adapters/qwik-adapter.js +0 -259
- package/src/client/adapters/qwik-adapter.ts +0 -345
- package/src/client/adapters/react-adapter.js +0 -220
- package/src/client/adapters/react-adapter.ts +0 -353
- package/src/client/adapters/solid-adapter.js +0 -295
- package/src/client/adapters/solid-adapter.ts +0 -451
- package/src/client/adapters/svelte-adapter.js +0 -368
- package/src/client/adapters/svelte-adapter.ts +0 -524
- package/src/client/adapters/vue-adapter.js +0 -278
- package/src/client/adapters/vue-adapter.ts +0 -467
- package/src/client/components.js +0 -23
- package/src/client/css-hmr-handler.js +0 -263
- package/src/client/framework-adapter.js +0 -283
- package/src/client/hmr-coordinator.js +0 -274
|
@@ -1,175 +1,175 @@
|
|
|
1
|
-
import type { Integration } from "@useavalon/core";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { statSync } from "node:fs";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Find the root of the Avalon monorepo by looking for packages/integrations
|
|
7
|
-
*/
|
|
8
|
-
function findMonorepoRoot(): string {
|
|
9
|
-
let currentDir = process.cwd();
|
|
10
|
-
|
|
11
|
-
// Walk up the directory tree looking for packages/integrations
|
|
12
|
-
for (let i = 0; i < 10; i++) {
|
|
13
|
-
try {
|
|
14
|
-
const integrationsPath = join(currentDir, "packages", "integrations");
|
|
15
|
-
const stat = statSync(integrationsPath);
|
|
16
|
-
if (stat.isDirectory()) {
|
|
17
|
-
return currentDir;
|
|
18
|
-
}
|
|
19
|
-
} catch {
|
|
20
|
-
// Directory doesn't exist, try parent
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const parent = dirname(currentDir);
|
|
24
|
-
if (parent === currentDir) {
|
|
25
|
-
// Reached root, stop
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
currentDir = parent;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Fallback to cwd
|
|
32
|
-
return process.cwd();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* IntegrationRegistry manages loaded framework integrations.
|
|
37
|
-
* It provides registration, retrieval, and dynamic loading of integrations.
|
|
38
|
-
*/
|
|
39
|
-
export class IntegrationRegistry {
|
|
40
|
-
private readonly integrations = new Map<string, Integration>();
|
|
41
|
-
private readonly loadingPromises = new Map<string, Promise<Integration>>();
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Register an integration instance
|
|
45
|
-
*/
|
|
46
|
-
register(integration: Integration): void {
|
|
47
|
-
if (!integration.name) {
|
|
48
|
-
throw new Error("Integration must have a name");
|
|
49
|
-
}
|
|
50
|
-
this.integrations.set(integration.name, integration);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Get a registered integration by name
|
|
55
|
-
*/
|
|
56
|
-
get(name: string): Integration | undefined {
|
|
57
|
-
return this.integrations.get(name);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Check if an integration is registered
|
|
62
|
-
*/
|
|
63
|
-
has(name: string): boolean {
|
|
64
|
-
return this.integrations.has(name);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Dynamically load an integration by name
|
|
69
|
-
* Returns cached integration if already loaded
|
|
70
|
-
*/
|
|
71
|
-
async load(name: string): Promise<Integration> {
|
|
72
|
-
// Check if already loaded
|
|
73
|
-
const existing = this.integrations.get(name);
|
|
74
|
-
if (existing) {
|
|
75
|
-
return existing;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Check if currently loading (prevent duplicate loads)
|
|
79
|
-
const loadingPromise = this.loadingPromises.get(name);
|
|
80
|
-
if (loadingPromise) {
|
|
81
|
-
return loadingPromise;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Start loading
|
|
85
|
-
const promise = this.loadIntegration(name);
|
|
86
|
-
this.loadingPromises.set(name, promise);
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
const integration = await promise;
|
|
90
|
-
this.register(integration);
|
|
91
|
-
return integration;
|
|
92
|
-
} finally {
|
|
93
|
-
this.loadingPromises.delete(name);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private async loadIntegration(name: string): Promise<Integration> {
|
|
98
|
-
const integrationKey = `${name}Integration`;
|
|
99
|
-
|
|
100
|
-
// 1. Try loading from the installed npm package first (@useavalon/<name>)
|
|
101
|
-
try {
|
|
102
|
-
const packageName = `@useavalon/${name}`;
|
|
103
|
-
const module = await import(/* @vite-ignore */ packageName);
|
|
104
|
-
const integration = module[integrationKey] || module.default;
|
|
105
|
-
if (integration) return integration as Integration;
|
|
106
|
-
} catch {
|
|
107
|
-
// Package not installed or import failed — try monorepo path
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// 2. Monorepo fallback: resolve via packages/integrations/<name>/mod.ts
|
|
111
|
-
try {
|
|
112
|
-
const monorepoRoot = findMonorepoRoot();
|
|
113
|
-
const integrationPath = join(monorepoRoot, "packages", "integrations", name, "mod.ts");
|
|
114
|
-
const fileUrl = `file://${integrationPath}`;
|
|
115
|
-
const module = await import(/* @vite-ignore */ fileUrl);
|
|
116
|
-
const integration = module[integrationKey] || module.default;
|
|
117
|
-
if (integration) return integration as Integration;
|
|
118
|
-
} catch {
|
|
119
|
-
// Monorepo path also failed
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
throw new Error(
|
|
123
|
-
`Failed to load integration for framework '${name}'. ` +
|
|
124
|
-
`Make sure @useavalon/${name} is installed.\n` +
|
|
125
|
-
`Install it with: bun add @useavalon/${name}`,
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Get all registered integrations
|
|
131
|
-
*/
|
|
132
|
-
getAll(): Integration[] {
|
|
133
|
-
return Array.from(this.integrations.values());
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Get all registered integration names
|
|
138
|
-
*/
|
|
139
|
-
getAllNames(): string[] {
|
|
140
|
-
return Array.from(this.integrations.keys());
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Unregister an integration
|
|
145
|
-
*/
|
|
146
|
-
unregister(name: string): boolean {
|
|
147
|
-
return this.integrations.delete(name);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Clear all registered integrations
|
|
152
|
-
*/
|
|
153
|
-
clear(): void {
|
|
154
|
-
this.integrations.clear();
|
|
155
|
-
this.loadingPromises.clear();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Get the count of registered integrations
|
|
160
|
-
*/
|
|
161
|
-
get size(): number {
|
|
162
|
-
return this.integrations.size;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Global singleton registry instance
|
|
167
|
-
// Use globalThis to ensure the registry is shared across all module contexts
|
|
168
|
-
// This is important because Vite's ssrLoadModule creates new module contexts
|
|
169
|
-
declare global {
|
|
170
|
-
var __avalonIntegrationRegistry: IntegrationRegistry | undefined;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
globalThis.__avalonIntegrationRegistry ??= new IntegrationRegistry();
|
|
174
|
-
|
|
175
|
-
export const registry = globalThis.__avalonIntegrationRegistry;
|
|
1
|
+
import type { Integration } from "@useavalon/core";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { statSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Find the root of the Avalon monorepo by looking for packages/integrations
|
|
7
|
+
*/
|
|
8
|
+
function findMonorepoRoot(): string {
|
|
9
|
+
let currentDir = process.cwd();
|
|
10
|
+
|
|
11
|
+
// Walk up the directory tree looking for packages/integrations
|
|
12
|
+
for (let i = 0; i < 10; i++) {
|
|
13
|
+
try {
|
|
14
|
+
const integrationsPath = join(currentDir, "packages", "integrations");
|
|
15
|
+
const stat = statSync(integrationsPath);
|
|
16
|
+
if (stat.isDirectory()) {
|
|
17
|
+
return currentDir;
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
// Directory doesn't exist, try parent
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const parent = dirname(currentDir);
|
|
24
|
+
if (parent === currentDir) {
|
|
25
|
+
// Reached root, stop
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
currentDir = parent;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Fallback to cwd
|
|
32
|
+
return process.cwd();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* IntegrationRegistry manages loaded framework integrations.
|
|
37
|
+
* It provides registration, retrieval, and dynamic loading of integrations.
|
|
38
|
+
*/
|
|
39
|
+
export class IntegrationRegistry {
|
|
40
|
+
private readonly integrations = new Map<string, Integration>();
|
|
41
|
+
private readonly loadingPromises = new Map<string, Promise<Integration>>();
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Register an integration instance
|
|
45
|
+
*/
|
|
46
|
+
register(integration: Integration): void {
|
|
47
|
+
if (!integration.name) {
|
|
48
|
+
throw new Error("Integration must have a name");
|
|
49
|
+
}
|
|
50
|
+
this.integrations.set(integration.name, integration);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get a registered integration by name
|
|
55
|
+
*/
|
|
56
|
+
get(name: string): Integration | undefined {
|
|
57
|
+
return this.integrations.get(name);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Check if an integration is registered
|
|
62
|
+
*/
|
|
63
|
+
has(name: string): boolean {
|
|
64
|
+
return this.integrations.has(name);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Dynamically load an integration by name
|
|
69
|
+
* Returns cached integration if already loaded
|
|
70
|
+
*/
|
|
71
|
+
async load(name: string): Promise<Integration> {
|
|
72
|
+
// Check if already loaded
|
|
73
|
+
const existing = this.integrations.get(name);
|
|
74
|
+
if (existing) {
|
|
75
|
+
return existing;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check if currently loading (prevent duplicate loads)
|
|
79
|
+
const loadingPromise = this.loadingPromises.get(name);
|
|
80
|
+
if (loadingPromise) {
|
|
81
|
+
return loadingPromise;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Start loading
|
|
85
|
+
const promise = this.loadIntegration(name);
|
|
86
|
+
this.loadingPromises.set(name, promise);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const integration = await promise;
|
|
90
|
+
this.register(integration);
|
|
91
|
+
return integration;
|
|
92
|
+
} finally {
|
|
93
|
+
this.loadingPromises.delete(name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private async loadIntegration(name: string): Promise<Integration> {
|
|
98
|
+
const integrationKey = `${name}Integration`;
|
|
99
|
+
|
|
100
|
+
// 1. Try loading from the installed npm package first (@useavalon/<name>)
|
|
101
|
+
try {
|
|
102
|
+
const packageName = `@useavalon/${name}`;
|
|
103
|
+
const module = await import(/* @vite-ignore */ packageName);
|
|
104
|
+
const integration = module[integrationKey] || module.default;
|
|
105
|
+
if (integration) return integration as Integration;
|
|
106
|
+
} catch {
|
|
107
|
+
// Package not installed or import failed — try monorepo path
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 2. Monorepo fallback: resolve via packages/integrations/<name>/mod.ts
|
|
111
|
+
try {
|
|
112
|
+
const monorepoRoot = findMonorepoRoot();
|
|
113
|
+
const integrationPath = join(monorepoRoot, "packages", "integrations", name, "mod.ts");
|
|
114
|
+
const fileUrl = `file://${integrationPath}`;
|
|
115
|
+
const module = await import(/* @vite-ignore */ fileUrl);
|
|
116
|
+
const integration = module[integrationKey] || module.default;
|
|
117
|
+
if (integration) return integration as Integration;
|
|
118
|
+
} catch {
|
|
119
|
+
// Monorepo path also failed
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
throw new Error(
|
|
123
|
+
`Failed to load integration for framework '${name}'. ` +
|
|
124
|
+
`Make sure @useavalon/${name} is installed.\n` +
|
|
125
|
+
`Install it with: bun add @useavalon/${name}`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get all registered integrations
|
|
131
|
+
*/
|
|
132
|
+
getAll(): Integration[] {
|
|
133
|
+
return Array.from(this.integrations.values());
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get all registered integration names
|
|
138
|
+
*/
|
|
139
|
+
getAllNames(): string[] {
|
|
140
|
+
return Array.from(this.integrations.keys());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Unregister an integration
|
|
145
|
+
*/
|
|
146
|
+
unregister(name: string): boolean {
|
|
147
|
+
return this.integrations.delete(name);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Clear all registered integrations
|
|
152
|
+
*/
|
|
153
|
+
clear(): void {
|
|
154
|
+
this.integrations.clear();
|
|
155
|
+
this.loadingPromises.clear();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get the count of registered integrations
|
|
160
|
+
*/
|
|
161
|
+
get size(): number {
|
|
162
|
+
return this.integrations.size;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Global singleton registry instance
|
|
167
|
+
// Use globalThis to ensure the registry is shared across all module contexts
|
|
168
|
+
// This is important because Vite's ssrLoadModule creates new module contexts
|
|
169
|
+
declare global {
|
|
170
|
+
var __avalonIntegrationRegistry: IntegrationRegistry | undefined;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
globalThis.__avalonIntegrationRegistry ??= new IntegrationRegistry();
|
|
174
|
+
|
|
175
|
+
export const registry = globalThis.__avalonIntegrationRegistry;
|