@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,21 +1,21 @@
|
|
|
1
|
-
export { type PropExtractionResult, FALLBACK_PROPS, extractVueProps } from "./vue.ts";
|
|
2
|
-
export { extractSvelteProps } from "./svelte.ts";
|
|
3
|
-
export { extractLitProps } from "./lit.ts";
|
|
4
|
-
export { extractSolidProps } from "./solid.ts";
|
|
5
|
-
export { extractQwikProps } from "./qwik.ts";
|
|
6
|
-
|
|
7
|
-
import type { PropExtractionResult } from "./vue.ts";
|
|
8
|
-
import { extractVueProps } from "./vue.ts";
|
|
9
|
-
import { extractSvelteProps } from "./svelte.ts";
|
|
10
|
-
import { extractLitProps } from "./lit.ts";
|
|
11
|
-
import { extractSolidProps } from "./solid.ts";
|
|
12
|
-
import { extractQwikProps } from "./qwik.ts";
|
|
13
|
-
|
|
14
|
-
/** Maps framework name to its prop extractor function */
|
|
15
|
-
export const EXTRACTOR_MAP: Record<string, (source: string) => PropExtractionResult> = {
|
|
16
|
-
vue: extractVueProps,
|
|
17
|
-
svelte: extractSvelteProps,
|
|
18
|
-
lit: extractLitProps,
|
|
19
|
-
solid: extractSolidProps,
|
|
20
|
-
qwik: extractQwikProps,
|
|
21
|
-
};
|
|
1
|
+
export { type PropExtractionResult, FALLBACK_PROPS, extractVueProps } from "./vue.ts";
|
|
2
|
+
export { extractSvelteProps } from "./svelte.ts";
|
|
3
|
+
export { extractLitProps } from "./lit.ts";
|
|
4
|
+
export { extractSolidProps } from "./solid.ts";
|
|
5
|
+
export { extractQwikProps } from "./qwik.ts";
|
|
6
|
+
|
|
7
|
+
import type { PropExtractionResult } from "./vue.ts";
|
|
8
|
+
import { extractVueProps } from "./vue.ts";
|
|
9
|
+
import { extractSvelteProps } from "./svelte.ts";
|
|
10
|
+
import { extractLitProps } from "./lit.ts";
|
|
11
|
+
import { extractSolidProps } from "./solid.ts";
|
|
12
|
+
import { extractQwikProps } from "./qwik.ts";
|
|
13
|
+
|
|
14
|
+
/** Maps framework name to its prop extractor function */
|
|
15
|
+
export const EXTRACTOR_MAP: Record<string, (source: string) => PropExtractionResult> = {
|
|
16
|
+
vue: extractVueProps,
|
|
17
|
+
svelte: extractSvelteProps,
|
|
18
|
+
lit: extractLitProps,
|
|
19
|
+
solid: extractSolidProps,
|
|
20
|
+
qwik: extractQwikProps,
|
|
21
|
+
};
|
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
import { FALLBACK_PROPS, type PropExtractionResult } from "./vue.ts";
|
|
2
|
-
|
|
3
|
-
/** Mapping from Lit type constructors to TypeScript type strings */
|
|
4
|
-
const LIT_TYPE_MAP: Record<string, string> = {
|
|
5
|
-
String: "string",
|
|
6
|
-
Number: "number",
|
|
7
|
-
Boolean: "boolean",
|
|
8
|
-
Array: "unknown[]",
|
|
9
|
-
Object: "Record<string, unknown>",
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Extract props from a Lit element source string.
|
|
14
|
-
*
|
|
15
|
-
* Parses `static properties = { ... }` blocks and maps Lit type
|
|
16
|
-
* constructors to TypeScript types. Properties with `state: true`
|
|
17
|
-
* are excluded (internal state, not public props).
|
|
18
|
-
*
|
|
19
|
-
* Never throws — returns fallback on any failure.
|
|
20
|
-
*/
|
|
21
|
-
export function extractLitProps(source: string): PropExtractionResult {
|
|
22
|
-
try {
|
|
23
|
-
const block = extractStaticPropertiesBlock(source);
|
|
24
|
-
if (block === null) {
|
|
25
|
-
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const props = parsePropertyEntries(block);
|
|
29
|
-
if (props.length === 0) {
|
|
30
|
-
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const fields = props.map((p) => p.name + "?: " + p.tsType).join("; ");
|
|
34
|
-
const propsType = "{ " + fields + " }";
|
|
35
|
-
return { propsType, fallback: false };
|
|
36
|
-
} catch {
|
|
37
|
-
console.warn(
|
|
38
|
-
"[avalon] Failed to extract Lit props — falling back to Record<string, unknown>",
|
|
39
|
-
);
|
|
40
|
-
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Extract the content inside `static properties = { ... }`.
|
|
46
|
-
* Uses brace-counting to handle nested objects.
|
|
47
|
-
* Returns the inner content (without outer braces), or null if not found.
|
|
48
|
-
*/
|
|
49
|
-
function extractStaticPropertiesBlock(source: string): string | null {
|
|
50
|
-
const marker = /static\s+properties\s*=\s*\{/;
|
|
51
|
-
const match = marker.exec(source);
|
|
52
|
-
if (!match) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Position of the opening brace
|
|
57
|
-
const openBrace = match.index + match[0].length - 1;
|
|
58
|
-
let depth = 1;
|
|
59
|
-
let i = openBrace + 1;
|
|
60
|
-
|
|
61
|
-
while (i < source.length && depth > 0) {
|
|
62
|
-
if (source[i] === "{") depth++;
|
|
63
|
-
else if (source[i] === "}") depth--;
|
|
64
|
-
i++;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (depth !== 0) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Return content between the outer braces
|
|
72
|
-
return source.slice(openBrace + 1, i - 1);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
interface ParsedProp {
|
|
76
|
-
name: string;
|
|
77
|
-
tsType: string;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Parse individual property entries from the static properties block content.
|
|
82
|
-
* Each entry looks like: `propName: { type: Constructor, ... }`
|
|
83
|
-
* Filters out entries with `state: true`.
|
|
84
|
-
*/
|
|
85
|
-
function parsePropertyEntries(block: string): ParsedProp[] {
|
|
86
|
-
const props: ParsedProp[] = [];
|
|
87
|
-
|
|
88
|
-
// Match each property entry: name: { ... }
|
|
89
|
-
// We use a regex to find property names followed by `{`, then brace-count
|
|
90
|
-
const entryRegex = /(\w+)\s*:\s*\{/g;
|
|
91
|
-
let entryMatch: RegExpExecArray | null;
|
|
92
|
-
|
|
93
|
-
while ((entryMatch = entryRegex.exec(block)) !== null) {
|
|
94
|
-
const name = entryMatch[1];
|
|
95
|
-
const openIdx = entryMatch.index + entryMatch[0].length - 1;
|
|
96
|
-
|
|
97
|
-
// Extract the balanced { ... } for this entry
|
|
98
|
-
const entryBody = extractBalancedBraces(block, openIdx);
|
|
99
|
-
if (entryBody === null) continue;
|
|
100
|
-
|
|
101
|
-
// Skip state properties
|
|
102
|
-
if (/\bstate\s*:\s*true\b/.test(entryBody)) continue;
|
|
103
|
-
|
|
104
|
-
// Extract the type constructor
|
|
105
|
-
const typeMatch = new RegExp(/\btype\s*:\s*(\w+)/).exec(entryBody);
|
|
106
|
-
const litType = typeMatch ? typeMatch[1] : null;
|
|
107
|
-
const tsType = litType && litType in LIT_TYPE_MAP
|
|
108
|
-
? LIT_TYPE_MAP[litType]
|
|
109
|
-
: "unknown";
|
|
110
|
-
|
|
111
|
-
props.push({ name, tsType });
|
|
112
|
-
|
|
113
|
-
// Advance regex past this entry to avoid re-matching nested braces
|
|
114
|
-
entryRegex.lastIndex = openIdx + (entryBody.length);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return props;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Extract a balanced `{ ... }` block starting at the given index.
|
|
122
|
-
* Returns the content between the braces (excluding outer braces), or null.
|
|
123
|
-
*/
|
|
124
|
-
function extractBalancedBraces(source: string, startIdx: number): string | null {
|
|
125
|
-
if (source[startIdx] !== "{") return null;
|
|
126
|
-
|
|
127
|
-
let depth = 0;
|
|
128
|
-
let i = startIdx;
|
|
129
|
-
|
|
130
|
-
while (i < source.length) {
|
|
131
|
-
if (source[i] === "{") depth++;
|
|
132
|
-
else if (source[i] === "}") depth--;
|
|
133
|
-
if (depth === 0) {
|
|
134
|
-
return source.slice(startIdx + 1, i);
|
|
135
|
-
}
|
|
136
|
-
i++;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
1
|
+
import { FALLBACK_PROPS, type PropExtractionResult } from "./vue.ts";
|
|
2
|
+
|
|
3
|
+
/** Mapping from Lit type constructors to TypeScript type strings */
|
|
4
|
+
const LIT_TYPE_MAP: Record<string, string> = {
|
|
5
|
+
String: "string",
|
|
6
|
+
Number: "number",
|
|
7
|
+
Boolean: "boolean",
|
|
8
|
+
Array: "unknown[]",
|
|
9
|
+
Object: "Record<string, unknown>",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Extract props from a Lit element source string.
|
|
14
|
+
*
|
|
15
|
+
* Parses `static properties = { ... }` blocks and maps Lit type
|
|
16
|
+
* constructors to TypeScript types. Properties with `state: true`
|
|
17
|
+
* are excluded (internal state, not public props).
|
|
18
|
+
*
|
|
19
|
+
* Never throws — returns fallback on any failure.
|
|
20
|
+
*/
|
|
21
|
+
export function extractLitProps(source: string): PropExtractionResult {
|
|
22
|
+
try {
|
|
23
|
+
const block = extractStaticPropertiesBlock(source);
|
|
24
|
+
if (block === null) {
|
|
25
|
+
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const props = parsePropertyEntries(block);
|
|
29
|
+
if (props.length === 0) {
|
|
30
|
+
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const fields = props.map((p) => p.name + "?: " + p.tsType).join("; ");
|
|
34
|
+
const propsType = "{ " + fields + " }";
|
|
35
|
+
return { propsType, fallback: false };
|
|
36
|
+
} catch {
|
|
37
|
+
console.warn(
|
|
38
|
+
"[avalon] Failed to extract Lit props — falling back to Record<string, unknown>",
|
|
39
|
+
);
|
|
40
|
+
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Extract the content inside `static properties = { ... }`.
|
|
46
|
+
* Uses brace-counting to handle nested objects.
|
|
47
|
+
* Returns the inner content (without outer braces), or null if not found.
|
|
48
|
+
*/
|
|
49
|
+
function extractStaticPropertiesBlock(source: string): string | null {
|
|
50
|
+
const marker = /static\s+properties\s*=\s*\{/;
|
|
51
|
+
const match = marker.exec(source);
|
|
52
|
+
if (!match) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Position of the opening brace
|
|
57
|
+
const openBrace = match.index + match[0].length - 1;
|
|
58
|
+
let depth = 1;
|
|
59
|
+
let i = openBrace + 1;
|
|
60
|
+
|
|
61
|
+
while (i < source.length && depth > 0) {
|
|
62
|
+
if (source[i] === "{") depth++;
|
|
63
|
+
else if (source[i] === "}") depth--;
|
|
64
|
+
i++;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (depth !== 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Return content between the outer braces
|
|
72
|
+
return source.slice(openBrace + 1, i - 1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface ParsedProp {
|
|
76
|
+
name: string;
|
|
77
|
+
tsType: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Parse individual property entries from the static properties block content.
|
|
82
|
+
* Each entry looks like: `propName: { type: Constructor, ... }`
|
|
83
|
+
* Filters out entries with `state: true`.
|
|
84
|
+
*/
|
|
85
|
+
function parsePropertyEntries(block: string): ParsedProp[] {
|
|
86
|
+
const props: ParsedProp[] = [];
|
|
87
|
+
|
|
88
|
+
// Match each property entry: name: { ... }
|
|
89
|
+
// We use a regex to find property names followed by `{`, then brace-count
|
|
90
|
+
const entryRegex = /(\w+)\s*:\s*\{/g;
|
|
91
|
+
let entryMatch: RegExpExecArray | null;
|
|
92
|
+
|
|
93
|
+
while ((entryMatch = entryRegex.exec(block)) !== null) {
|
|
94
|
+
const name = entryMatch[1];
|
|
95
|
+
const openIdx = entryMatch.index + entryMatch[0].length - 1;
|
|
96
|
+
|
|
97
|
+
// Extract the balanced { ... } for this entry
|
|
98
|
+
const entryBody = extractBalancedBraces(block, openIdx);
|
|
99
|
+
if (entryBody === null) continue;
|
|
100
|
+
|
|
101
|
+
// Skip state properties
|
|
102
|
+
if (/\bstate\s*:\s*true\b/.test(entryBody)) continue;
|
|
103
|
+
|
|
104
|
+
// Extract the type constructor
|
|
105
|
+
const typeMatch = new RegExp(/\btype\s*:\s*(\w+)/).exec(entryBody);
|
|
106
|
+
const litType = typeMatch ? typeMatch[1] : null;
|
|
107
|
+
const tsType = litType && litType in LIT_TYPE_MAP
|
|
108
|
+
? LIT_TYPE_MAP[litType]
|
|
109
|
+
: "unknown";
|
|
110
|
+
|
|
111
|
+
props.push({ name, tsType });
|
|
112
|
+
|
|
113
|
+
// Advance regex past this entry to avoid re-matching nested braces
|
|
114
|
+
entryRegex.lastIndex = openIdx + (entryBody.length);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return props;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Extract a balanced `{ ... }` block starting at the given index.
|
|
122
|
+
* Returns the content between the braces (excluding outer braces), or null.
|
|
123
|
+
*/
|
|
124
|
+
function extractBalancedBraces(source: string, startIdx: number): string | null {
|
|
125
|
+
if (source[startIdx] !== "{") return null;
|
|
126
|
+
|
|
127
|
+
let depth = 0;
|
|
128
|
+
let i = startIdx;
|
|
129
|
+
|
|
130
|
+
while (i < source.length) {
|
|
131
|
+
if (source[i] === "{") depth++;
|
|
132
|
+
else if (source[i] === "}") depth--;
|
|
133
|
+
if (depth === 0) {
|
|
134
|
+
return source.slice(startIdx + 1, i);
|
|
135
|
+
}
|
|
136
|
+
i++;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { PropExtractionResult } from "./vue.ts";
|
|
2
|
-
import { FALLBACK_PROPS } from "./vue.ts";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Extract props type from a Qwik component file.
|
|
6
|
-
* Qwik components use component$(() => ...) — props are typed via the
|
|
7
|
-
* generic parameter or a Props interface. For now we fall back to
|
|
8
|
-
* Record<string, unknown> since Qwik's JSX types aren't Preact-compatible
|
|
9
|
-
* and the sidecar just needs to expose the island prop.
|
|
10
|
-
*/
|
|
11
|
-
export function extractQwikProps(_source: string): PropExtractionResult {
|
|
12
|
-
return {
|
|
13
|
-
propsType: FALLBACK_PROPS,
|
|
14
|
-
fallback: false
|
|
15
|
-
};
|
|
16
|
-
}
|
|
1
|
+
import type { PropExtractionResult } from "./vue.ts";
|
|
2
|
+
import { FALLBACK_PROPS } from "./vue.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extract props type from a Qwik component file.
|
|
6
|
+
* Qwik components use component$(() => ...) — props are typed via the
|
|
7
|
+
* generic parameter or a Props interface. For now we fall back to
|
|
8
|
+
* Record<string, unknown> since Qwik's JSX types aren't Preact-compatible
|
|
9
|
+
* and the sidecar just needs to expose the island prop.
|
|
10
|
+
*/
|
|
11
|
+
export function extractQwikProps(_source: string): PropExtractionResult {
|
|
12
|
+
return {
|
|
13
|
+
propsType: FALLBACK_PROPS,
|
|
14
|
+
fallback: false
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
import { FALLBACK_PROPS, type PropExtractionResult } from "./vue.ts";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Extract props from a Solid component source string.
|
|
5
|
-
*
|
|
6
|
-
* Supports two patterns:
|
|
7
|
-
* 1. `export default function Name(props: { ... })` — named function export
|
|
8
|
-
* 2. `export default (props: { ... }) =>` — arrow function export
|
|
9
|
-
*
|
|
10
|
-
* Uses brace-counting to handle nested types in the props parameter.
|
|
11
|
-
* Never throws — returns fallback on any failure.
|
|
12
|
-
*/
|
|
13
|
-
export function extractSolidProps(source: string): PropExtractionResult {
|
|
14
|
-
try {
|
|
15
|
-
// Try named function pattern first
|
|
16
|
-
const namedResult = extractFromNamedFunction(source);
|
|
17
|
-
if (namedResult !== null) {
|
|
18
|
-
return { propsType: namedResult, fallback: false };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Try arrow function pattern
|
|
22
|
-
const arrowResult = extractFromArrowFunction(source);
|
|
23
|
-
if (arrowResult !== null) {
|
|
24
|
-
return { propsType: arrowResult, fallback: false };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
28
|
-
} catch {
|
|
29
|
-
console.warn(
|
|
30
|
-
"[avalon] Failed to extract Solid props — falling back to Record<string, unknown>",
|
|
31
|
-
);
|
|
32
|
-
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Extract props type from `export default function Name(props: { ... })`.
|
|
38
|
-
* Returns the type literal string, or null if not found.
|
|
39
|
-
*/
|
|
40
|
-
function extractFromNamedFunction(source: string): string | null {
|
|
41
|
-
// Match: export default function <Name>(props:
|
|
42
|
-
const regex = /export\s+default\s+function\s+\w+\s*\(\s*props\s*:\s*/;
|
|
43
|
-
const match = regex.exec(source);
|
|
44
|
-
if (!match) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const typeStart = match.index + match[0].length;
|
|
49
|
-
return extractPropsType(source, typeStart);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Extract props type from `export default (props: { ... }) =>`.
|
|
54
|
-
* Returns the type literal string, or null if not found.
|
|
55
|
-
*/
|
|
56
|
-
function extractFromArrowFunction(source: string): string | null {
|
|
57
|
-
// Match: export default (props:
|
|
58
|
-
const regex = /export\s+default\s+\(\s*props\s*:\s*/;
|
|
59
|
-
const match = regex.exec(source);
|
|
60
|
-
if (!match) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const typeStart = match.index + match[0].length;
|
|
65
|
-
return extractPropsType(source, typeStart);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Extract a props type starting at the given index in the source.
|
|
70
|
-
* Handles both inline type literals `{ ... }` using brace-counting
|
|
71
|
-
* and simple type references like `Props`.
|
|
72
|
-
* Returns the trimmed type string, or null if extraction fails.
|
|
73
|
-
*/
|
|
74
|
-
function extractPropsType(source: string, startIdx: number): string | null {
|
|
75
|
-
// Skip leading whitespace
|
|
76
|
-
let i = startIdx;
|
|
77
|
-
while (i < source.length && /\s/.test(source[i])) {
|
|
78
|
-
i++;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (i >= source.length) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// If it starts with `{`, use brace-counting for inline type literal
|
|
86
|
-
if (source[i] === "{") {
|
|
87
|
-
return extractBalancedBraces(source, i);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Otherwise it's a type reference — read until `)` or `,`
|
|
91
|
-
const remaining = source.slice(i);
|
|
92
|
-
const refMatch = new RegExp(/^([A-Za-z_$][\w$]*(?:<[^>]*>)?)/).exec(remaining);
|
|
93
|
-
if (refMatch) {
|
|
94
|
-
return refMatch[1].trim();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Extract a balanced `{ ... }` block starting at the given index.
|
|
102
|
-
* Returns the full string including the outer braces, or null if unbalanced.
|
|
103
|
-
*/
|
|
104
|
-
function extractBalancedBraces(source: string, startIdx: number): string | null {
|
|
105
|
-
if (source[startIdx] !== "{") {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let depth = 0;
|
|
110
|
-
let i = startIdx;
|
|
111
|
-
|
|
112
|
-
while (i < source.length) {
|
|
113
|
-
if (source[i] === "{") {
|
|
114
|
-
depth++;
|
|
115
|
-
} else if (source[i] === "}") {
|
|
116
|
-
depth--;
|
|
117
|
-
if (depth === 0) {
|
|
118
|
-
return source.slice(startIdx, i + 1).trim();
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
i++;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return null; // unbalanced
|
|
125
|
-
}
|
|
1
|
+
import { FALLBACK_PROPS, type PropExtractionResult } from "./vue.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extract props from a Solid component source string.
|
|
5
|
+
*
|
|
6
|
+
* Supports two patterns:
|
|
7
|
+
* 1. `export default function Name(props: { ... })` — named function export
|
|
8
|
+
* 2. `export default (props: { ... }) =>` — arrow function export
|
|
9
|
+
*
|
|
10
|
+
* Uses brace-counting to handle nested types in the props parameter.
|
|
11
|
+
* Never throws — returns fallback on any failure.
|
|
12
|
+
*/
|
|
13
|
+
export function extractSolidProps(source: string): PropExtractionResult {
|
|
14
|
+
try {
|
|
15
|
+
// Try named function pattern first
|
|
16
|
+
const namedResult = extractFromNamedFunction(source);
|
|
17
|
+
if (namedResult !== null) {
|
|
18
|
+
return { propsType: namedResult, fallback: false };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Try arrow function pattern
|
|
22
|
+
const arrowResult = extractFromArrowFunction(source);
|
|
23
|
+
if (arrowResult !== null) {
|
|
24
|
+
return { propsType: arrowResult, fallback: false };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
28
|
+
} catch {
|
|
29
|
+
console.warn(
|
|
30
|
+
"[avalon] Failed to extract Solid props — falling back to Record<string, unknown>",
|
|
31
|
+
);
|
|
32
|
+
return { propsType: FALLBACK_PROPS, fallback: true };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Extract props type from `export default function Name(props: { ... })`.
|
|
38
|
+
* Returns the type literal string, or null if not found.
|
|
39
|
+
*/
|
|
40
|
+
function extractFromNamedFunction(source: string): string | null {
|
|
41
|
+
// Match: export default function <Name>(props:
|
|
42
|
+
const regex = /export\s+default\s+function\s+\w+\s*\(\s*props\s*:\s*/;
|
|
43
|
+
const match = regex.exec(source);
|
|
44
|
+
if (!match) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const typeStart = match.index + match[0].length;
|
|
49
|
+
return extractPropsType(source, typeStart);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extract props type from `export default (props: { ... }) =>`.
|
|
54
|
+
* Returns the type literal string, or null if not found.
|
|
55
|
+
*/
|
|
56
|
+
function extractFromArrowFunction(source: string): string | null {
|
|
57
|
+
// Match: export default (props:
|
|
58
|
+
const regex = /export\s+default\s+\(\s*props\s*:\s*/;
|
|
59
|
+
const match = regex.exec(source);
|
|
60
|
+
if (!match) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const typeStart = match.index + match[0].length;
|
|
65
|
+
return extractPropsType(source, typeStart);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Extract a props type starting at the given index in the source.
|
|
70
|
+
* Handles both inline type literals `{ ... }` using brace-counting
|
|
71
|
+
* and simple type references like `Props`.
|
|
72
|
+
* Returns the trimmed type string, or null if extraction fails.
|
|
73
|
+
*/
|
|
74
|
+
function extractPropsType(source: string, startIdx: number): string | null {
|
|
75
|
+
// Skip leading whitespace
|
|
76
|
+
let i = startIdx;
|
|
77
|
+
while (i < source.length && /\s/.test(source[i])) {
|
|
78
|
+
i++;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (i >= source.length) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If it starts with `{`, use brace-counting for inline type literal
|
|
86
|
+
if (source[i] === "{") {
|
|
87
|
+
return extractBalancedBraces(source, i);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Otherwise it's a type reference — read until `)` or `,`
|
|
91
|
+
const remaining = source.slice(i);
|
|
92
|
+
const refMatch = new RegExp(/^([A-Za-z_$][\w$]*(?:<[^>]*>)?)/).exec(remaining);
|
|
93
|
+
if (refMatch) {
|
|
94
|
+
return refMatch[1].trim();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Extract a balanced `{ ... }` block starting at the given index.
|
|
102
|
+
* Returns the full string including the outer braces, or null if unbalanced.
|
|
103
|
+
*/
|
|
104
|
+
function extractBalancedBraces(source: string, startIdx: number): string | null {
|
|
105
|
+
if (source[startIdx] !== "{") {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let depth = 0;
|
|
110
|
+
let i = startIdx;
|
|
111
|
+
|
|
112
|
+
while (i < source.length) {
|
|
113
|
+
if (source[i] === "{") {
|
|
114
|
+
depth++;
|
|
115
|
+
} else if (source[i] === "}") {
|
|
116
|
+
depth--;
|
|
117
|
+
if (depth === 0) {
|
|
118
|
+
return source.slice(startIdx, i + 1).trim();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
i++;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return null; // unbalanced
|
|
125
|
+
}
|