@teamvelix/velix 5.0.2 → 5.0.3
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 +129 -10
- package/dist/index.js +102 -66
- package/dist/index.js.map +1 -1
- package/dist/runtime/start-dev.js.map +1 -1
- package/dist/runtime/start-prod.js.map +1 -1
- package/dist/server/index.js +72 -36
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,11 @@ Velix is a lightweight but powerful React 19 framework featuring file-based rout
|
|
|
21
21
|
- 📦 **Edge Ready** — Deploy to any edge platform
|
|
22
22
|
- 🤖 **AI Assistant** — Built-in CLI AI for code generation
|
|
23
23
|
|
|
24
|
-
## 📦
|
|
24
|
+
## 📦 Installation
|
|
25
|
+
|
|
26
|
+
### Option 1: Create New App (Recommended)
|
|
27
|
+
|
|
28
|
+
The fastest way to get started:
|
|
25
29
|
|
|
26
30
|
```bash
|
|
27
31
|
npx create-velix-app@latest my-app
|
|
@@ -30,11 +34,53 @@ npm install
|
|
|
30
34
|
npm run dev
|
|
31
35
|
```
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
This will:
|
|
38
|
+
- ✅ Create a new Velix project with your chosen template
|
|
39
|
+
- ✅ Install all dependencies automatically
|
|
40
|
+
- ✅ Set up Tailwind CSS (optional)
|
|
41
|
+
- ✅ Configure TypeScript
|
|
42
|
+
|
|
43
|
+
### Option 2: Install CLI Globally
|
|
44
|
+
|
|
45
|
+
For multiple projects or advanced usage:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Install Velix CLI globally
|
|
49
|
+
npm install -g @teamvelix/cli
|
|
50
|
+
|
|
51
|
+
# Create a new project
|
|
52
|
+
velix create my-app
|
|
53
|
+
cd my-app
|
|
54
|
+
npm install
|
|
55
|
+
|
|
56
|
+
# Start development
|
|
57
|
+
velix dev
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Option 3: Manual Installation
|
|
61
|
+
|
|
62
|
+
Add Velix to an existing project:
|
|
34
63
|
|
|
35
64
|
```bash
|
|
65
|
+
# Install core framework
|
|
36
66
|
npm install @teamvelix/velix react react-dom
|
|
37
|
-
|
|
67
|
+
|
|
68
|
+
# Install dev dependencies
|
|
69
|
+
npm install -D @teamvelix/cli typescript @types/react @types/react-dom
|
|
70
|
+
|
|
71
|
+
# Optional: Tailwind CSS
|
|
72
|
+
npm install -D tailwindcss postcss autoprefixer
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then create a `velix.config.ts` file:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { defineConfig } from "@teamvelix/velix";
|
|
79
|
+
|
|
80
|
+
export default defineConfig({
|
|
81
|
+
app: { name: "My App" },
|
|
82
|
+
server: { port: 3000 },
|
|
83
|
+
});
|
|
38
84
|
```
|
|
39
85
|
|
|
40
86
|
## 📁 Project Structure
|
|
@@ -83,24 +129,51 @@ export default defineConfig({
|
|
|
83
129
|
|
|
84
130
|
## 🛠️ CLI Commands
|
|
85
131
|
|
|
132
|
+
### Development
|
|
133
|
+
|
|
86
134
|
```bash
|
|
87
|
-
velix dev # Start
|
|
135
|
+
velix dev # Start development server with hot reload
|
|
88
136
|
velix build # Build for production
|
|
89
137
|
velix start # Start production server
|
|
90
|
-
velix doctor # Health check
|
|
138
|
+
velix doctor # Health check & diagnostics
|
|
139
|
+
velix info # Framework & environment info
|
|
140
|
+
```
|
|
91
141
|
|
|
92
|
-
|
|
142
|
+
### Generators
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
velix g page <name> # Generate a new page
|
|
93
146
|
velix g component <name> # Generate a component
|
|
94
147
|
velix g api <name> # Generate an API route
|
|
95
148
|
velix g layout <name> # Generate a layout
|
|
149
|
+
velix g action <name> # Generate a server action
|
|
96
150
|
velix g middleware <name> # Generate middleware
|
|
151
|
+
velix g hook <name> # Generate a custom hook
|
|
152
|
+
velix g context <name> # Generate a React context
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Project Creation
|
|
97
156
|
|
|
98
|
-
|
|
99
|
-
velix
|
|
100
|
-
velix
|
|
157
|
+
```bash
|
|
158
|
+
velix create <name> # Create new project (interactive)
|
|
159
|
+
velix create <name> --template=minimal # Use minimal template
|
|
160
|
+
velix create <name> --no-tailwind # Skip Tailwind CSS
|
|
101
161
|
```
|
|
102
162
|
|
|
103
|
-
|
|
163
|
+
### UI Components (Shadcn-style)
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
velix ui add button # Add button component
|
|
167
|
+
# More components coming soon
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Other
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
velix analyze # Bundle analysis (coming soon)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## 📚 Documentation
|
|
104
177
|
|
|
105
178
|
Comprehensive guides and API references:
|
|
106
179
|
|
|
@@ -110,6 +183,52 @@ Comprehensive guides and API references:
|
|
|
110
183
|
- **[Best Practices](./docs/best-practices.md)** - Development guidelines
|
|
111
184
|
- **[Roadmap](./docs/roadmap.md)** - Upcoming features and plugins
|
|
112
185
|
|
|
186
|
+
## 🔧 Troubleshooting
|
|
187
|
+
|
|
188
|
+
### Common Issues
|
|
189
|
+
|
|
190
|
+
**Module not found errors:**
|
|
191
|
+
```bash
|
|
192
|
+
# Clear node_modules and reinstall
|
|
193
|
+
rm -rf node_modules package-lock.json
|
|
194
|
+
npm install
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Tailwind CSS not working:**
|
|
198
|
+
```bash
|
|
199
|
+
# Ensure Tailwind is installed
|
|
200
|
+
npm install -D tailwindcss postcss autoprefixer
|
|
201
|
+
|
|
202
|
+
# Check that velix.config.ts includes tailwindPlugin
|
|
203
|
+
import { defineConfig, tailwindPlugin } from "@teamvelix/velix";
|
|
204
|
+
|
|
205
|
+
export default defineConfig({
|
|
206
|
+
plugins: [tailwindPlugin()]
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Port already in use:**
|
|
211
|
+
```bash
|
|
212
|
+
# Change port in velix.config.ts
|
|
213
|
+
export default defineConfig({
|
|
214
|
+
server: { port: 3001 }
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Getting Help
|
|
219
|
+
|
|
220
|
+
- 📖 Check the [documentation](./docs/README.md)
|
|
221
|
+
- 💬 Join our [Discord community](https://discord.gg/velix)
|
|
222
|
+
- 🐛 Report bugs on [GitHub Issues](https://github.com/Velixteam/velix/issues)
|
|
223
|
+
|
|
224
|
+
## 📦 NPM Packages
|
|
225
|
+
|
|
226
|
+
| Package | Version | Description |
|
|
227
|
+
|---------|---------|-------------|
|
|
228
|
+
| [@teamvelix/velix](https://npmjs.com/package/@teamvelix/velix) |  | Core framework |
|
|
229
|
+
| [create-velix-app](https://npmjs.com/package/create-velix-app) |  | Project scaffolding |
|
|
230
|
+
| [@teamvelix/cli](https://npmjs.com/package/@teamvelix/cli) |  | Command-line interface |
|
|
231
|
+
|
|
113
232
|
## 🤝 Contributing
|
|
114
233
|
|
|
115
234
|
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
|
package/dist/index.js
CHANGED
|
@@ -22,8 +22,8 @@ var image_optimizer_exports = {};
|
|
|
22
22
|
__export(image_optimizer_exports, {
|
|
23
23
|
handleImageOptimization: () => handleImageOptimization
|
|
24
24
|
});
|
|
25
|
-
import
|
|
26
|
-
import
|
|
25
|
+
import fs7 from "fs";
|
|
26
|
+
import path8 from "path";
|
|
27
27
|
async function handleImageOptimization(req, res, projectRoot) {
|
|
28
28
|
let sharp;
|
|
29
29
|
try {
|
|
@@ -48,14 +48,14 @@ async function handleImageOptimization(req, res, projectRoot) {
|
|
|
48
48
|
if (!response.ok) throw new Error(`Failed to fetch ${imageUrl}`);
|
|
49
49
|
imageBuffer = Buffer.from(await response.arrayBuffer());
|
|
50
50
|
} else {
|
|
51
|
-
const publicDir =
|
|
52
|
-
const resolvedPath =
|
|
53
|
-
if (!resolvedPath.startsWith(publicDir) || !
|
|
51
|
+
const publicDir = path8.join(projectRoot, "public");
|
|
52
|
+
const resolvedPath = path8.join(publicDir, imageUrl.startsWith("/") ? imageUrl.slice(1) : imageUrl);
|
|
53
|
+
if (!resolvedPath.startsWith(publicDir) || !fs7.existsSync(resolvedPath)) {
|
|
54
54
|
res.writeHead(404);
|
|
55
55
|
res.end("Image not found");
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
imageBuffer =
|
|
58
|
+
imageBuffer = fs7.readFileSync(resolvedPath);
|
|
59
59
|
}
|
|
60
60
|
if (!sharp) {
|
|
61
61
|
res.writeHead(200, {
|
|
@@ -715,8 +715,8 @@ function buildTree(routes) {
|
|
|
715
715
|
// server/index.ts
|
|
716
716
|
init_esm_shims();
|
|
717
717
|
import http from "http";
|
|
718
|
-
import
|
|
719
|
-
import
|
|
718
|
+
import fs8 from "fs";
|
|
719
|
+
import path9 from "path";
|
|
720
720
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL3 } from "url";
|
|
721
721
|
import React2 from "react";
|
|
722
722
|
import { renderToString } from "react-dom/server";
|
|
@@ -1026,6 +1026,8 @@ var builtinPlugins = {
|
|
|
1026
1026
|
// plugins/tailwind.ts
|
|
1027
1027
|
init_esm_shims();
|
|
1028
1028
|
import { spawnSync, spawn } from "child_process";
|
|
1029
|
+
import fs6 from "fs";
|
|
1030
|
+
import path7 from "path";
|
|
1029
1031
|
|
|
1030
1032
|
// logger.ts
|
|
1031
1033
|
init_esm_shims();
|
|
@@ -1077,14 +1079,14 @@ var logger = {
|
|
|
1077
1079
|
if (pagesDir) console.log(` ${c.bold}App:${c.reset} ${c.dim}${pagesDir}${c.reset}`);
|
|
1078
1080
|
console.log("");
|
|
1079
1081
|
},
|
|
1080
|
-
request(method,
|
|
1082
|
+
request(method, path11, status, time, extra = {}) {
|
|
1081
1083
|
const statusColor = getStatusColor(status);
|
|
1082
1084
|
const timeStr = fmtTime(time);
|
|
1083
1085
|
let badge = `${c.dim}\u25CB${c.reset}`;
|
|
1084
1086
|
if (extra.type === "dynamic" || extra.type === "ssr") badge = `${c.white}\u0192${c.reset}`;
|
|
1085
1087
|
else if (extra.type === "api") badge = `${c.cyan}\u03BB${c.reset}`;
|
|
1086
1088
|
const statusStr = `${statusColor}${status}${c.reset}`;
|
|
1087
|
-
console.log(` ${badge} ${c.white}${method}${c.reset} ${
|
|
1089
|
+
console.log(` ${badge} ${c.white}${method}${c.reset} ${path11} ${statusStr} ${c.dim}${timeStr}${c.reset}`);
|
|
1088
1090
|
},
|
|
1089
1091
|
info(msg) {
|
|
1090
1092
|
console.log(` ${c.cyan}\u2139${c.reset} ${msg}`);
|
|
@@ -1112,10 +1114,10 @@ var logger = {
|
|
|
1112
1114
|
plugin(name) {
|
|
1113
1115
|
console.log(` ${c.cyan}\u25C6${c.reset} Plugin ${c.dim}${name}${c.reset}`);
|
|
1114
1116
|
},
|
|
1115
|
-
route(
|
|
1117
|
+
route(path11, type) {
|
|
1116
1118
|
const typeLabel = type === "api" ? "\u03BB" : type === "dynamic" ? "\u0192" : "\u25CB";
|
|
1117
1119
|
const color = type === "api" ? c.cyan : type === "dynamic" ? c.white : c.dim;
|
|
1118
|
-
console.log(` ${color}${typeLabel}${c.reset} ${
|
|
1120
|
+
console.log(` ${color}${typeLabel}${c.reset} ${path11}`);
|
|
1119
1121
|
},
|
|
1120
1122
|
divider() {
|
|
1121
1123
|
console.log(`${c.dim} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}`);
|
|
@@ -1173,10 +1175,39 @@ function tailwindPlugin(options = {}) {
|
|
|
1173
1175
|
},
|
|
1174
1176
|
[PluginHooks.SERVER_START]: async (server, isDev) => {
|
|
1175
1177
|
if (!isDev) return;
|
|
1178
|
+
if (!fs6.existsSync(input)) {
|
|
1179
|
+
logger_default.warn(`Tailwind input file not found: ${input}`);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
const outputDir = path7.dirname(output);
|
|
1183
|
+
if (!fs6.existsSync(outputDir)) {
|
|
1184
|
+
fs6.mkdirSync(outputDir, { recursive: true });
|
|
1185
|
+
}
|
|
1186
|
+
logger_default.info("Building initial Tailwind CSS...");
|
|
1187
|
+
try {
|
|
1188
|
+
const buildResult = spawnSync("npx", ["tailwindcss", "-i", input, "-o", output], {
|
|
1189
|
+
cwd: process.cwd(),
|
|
1190
|
+
stdio: "pipe"
|
|
1191
|
+
});
|
|
1192
|
+
if (buildResult.error) {
|
|
1193
|
+
logger_default.error("Tailwind CSS not installed. Run: npm install -D tailwindcss");
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
if (buildResult.status !== 0) {
|
|
1197
|
+
const errorMsg = buildResult.stderr?.toString() || "Unknown error";
|
|
1198
|
+
logger_default.error(`Tailwind build failed: ${errorMsg}`);
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
logger_default.success("Tailwind CSS built successfully");
|
|
1202
|
+
} catch (err) {
|
|
1203
|
+
logger_default.error("Failed to build Tailwind CSS", err);
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1176
1206
|
logger_default.info("Starting Tailwind CSS watcher...");
|
|
1177
1207
|
const watcher = spawn("npx", ["tailwindcss", "-i", input, "-o", output, "--watch"], {
|
|
1178
1208
|
stdio: "pipe",
|
|
1179
|
-
cwd: process.cwd()
|
|
1209
|
+
cwd: process.cwd(),
|
|
1210
|
+
shell: false
|
|
1180
1211
|
});
|
|
1181
1212
|
watcher.stdout.on("data", (data) => {
|
|
1182
1213
|
const msg = data.toString().trim();
|
|
@@ -1186,7 +1217,7 @@ function tailwindPlugin(options = {}) {
|
|
|
1186
1217
|
});
|
|
1187
1218
|
watcher.stderr.on("data", (data) => {
|
|
1188
1219
|
const msg = data.toString().trim();
|
|
1189
|
-
if (msg) {
|
|
1220
|
+
if (msg && !msg.includes("warn")) {
|
|
1190
1221
|
logger_default.warn(`Tailwind: ${msg}`);
|
|
1191
1222
|
}
|
|
1192
1223
|
});
|
|
@@ -1198,9 +1229,14 @@ function tailwindPlugin(options = {}) {
|
|
|
1198
1229
|
logger_default.error(`Tailwind watcher exited with code ${code}`);
|
|
1199
1230
|
}
|
|
1200
1231
|
});
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1232
|
+
const cleanup = () => {
|
|
1233
|
+
if (watcher && !watcher.killed) {
|
|
1234
|
+
watcher.kill();
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
process.on("exit", cleanup);
|
|
1238
|
+
process.on("SIGINT", cleanup);
|
|
1239
|
+
process.on("SIGTERM", cleanup);
|
|
1204
1240
|
}
|
|
1205
1241
|
}
|
|
1206
1242
|
});
|
|
@@ -2445,7 +2481,7 @@ async function createServer(options = {}) {
|
|
|
2445
2481
|
await loadPlugins(projectRoot, config);
|
|
2446
2482
|
await pluginManager.runHook(PluginHooks.CONFIG, config);
|
|
2447
2483
|
const middlewareFns = await loadMiddleware(projectRoot);
|
|
2448
|
-
const appDir = config.resolvedAppDir ||
|
|
2484
|
+
const appDir = config.resolvedAppDir || path9.join(projectRoot, "app");
|
|
2449
2485
|
const routes = buildRouteTree(appDir);
|
|
2450
2486
|
await pluginManager.runHook(PluginHooks.ROUTES_LOADED, routes);
|
|
2451
2487
|
const startTime = Date.now();
|
|
@@ -2487,7 +2523,7 @@ async function createServer(options = {}) {
|
|
|
2487
2523
|
await serveVelixInternal(pathname, req, res, projectRoot);
|
|
2488
2524
|
return;
|
|
2489
2525
|
}
|
|
2490
|
-
const publicDir = config.resolvedPublicDir ||
|
|
2526
|
+
const publicDir = config.resolvedPublicDir || path9.join(projectRoot, "public");
|
|
2491
2527
|
if (await serveStaticFile(pathname, publicDir, res, isDev)) {
|
|
2492
2528
|
if (isDev) logger_default.request(req.method || "GET", pathname, 200, Date.now() - requestStart, { type: "static" });
|
|
2493
2529
|
return;
|
|
@@ -2556,12 +2592,12 @@ async function createServer(options = {}) {
|
|
|
2556
2592
|
};
|
|
2557
2593
|
}
|
|
2558
2594
|
async function serveStaticFile(pathname, publicDir, res, isDev = false) {
|
|
2559
|
-
const filePath =
|
|
2595
|
+
const filePath = path9.join(publicDir, pathname);
|
|
2560
2596
|
if (!filePath.startsWith(publicDir)) return false;
|
|
2561
|
-
if (!
|
|
2562
|
-
const ext =
|
|
2597
|
+
if (!fs8.existsSync(filePath) || fs8.statSync(filePath).isDirectory()) return false;
|
|
2598
|
+
const ext = path9.extname(filePath);
|
|
2563
2599
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
2564
|
-
const content =
|
|
2600
|
+
const content = fs8.readFileSync(filePath);
|
|
2565
2601
|
res.writeHead(200, {
|
|
2566
2602
|
"Content-Type": contentType,
|
|
2567
2603
|
"Content-Length": content.length,
|
|
@@ -2641,8 +2677,8 @@ async function handlePageRoute(route, routes, req, res, url, config, isDev, proj
|
|
|
2641
2677
|
let LayoutComponent = ({ children }) => React2.createElement(React2.Fragment, null, children);
|
|
2642
2678
|
let layoutParams = route.params;
|
|
2643
2679
|
try {
|
|
2644
|
-
const layoutPath =
|
|
2645
|
-
if (
|
|
2680
|
+
const layoutPath = path9.join(path9.dirname(route.filePath), "layout.tsx");
|
|
2681
|
+
if (fs8.existsSync(layoutPath)) {
|
|
2646
2682
|
const layoutMod = await import(`${pathToFileURL3(layoutPath).href}?t=${Date.now()}`);
|
|
2647
2683
|
if (layoutMod.metadata) {
|
|
2648
2684
|
metadata = { ...layoutMod.metadata, ...metadata };
|
|
@@ -2762,12 +2798,12 @@ async function serveVelixInternal(pathname, req, res, projectRoot) {
|
|
|
2762
2798
|
}
|
|
2763
2799
|
if (pathname === "/__velix/logo.webp") {
|
|
2764
2800
|
const __filename2 = fileURLToPath2(import.meta.url);
|
|
2765
|
-
const __dirname2 =
|
|
2766
|
-
const fallbackPath =
|
|
2767
|
-
const logoPath =
|
|
2768
|
-
if (
|
|
2801
|
+
const __dirname2 = path9.dirname(__filename2);
|
|
2802
|
+
const fallbackPath = path9.join(path9.dirname(pathToFileURL3(__dirname2).pathname), "..", "assets", "logo.webp");
|
|
2803
|
+
const logoPath = fs8.existsSync(fallbackPath) ? fallbackPath : path9.join(process.cwd(), "node_modules", "velix", "assets", "logo.webp");
|
|
2804
|
+
if (fs8.existsSync(logoPath)) {
|
|
2769
2805
|
res.writeHead(200, { "Content-Type": "image/webp", "Cache-Control": "public, max-age=31536000, immutable" });
|
|
2770
|
-
res.end(
|
|
2806
|
+
res.end(fs8.readFileSync(logoPath));
|
|
2771
2807
|
} else {
|
|
2772
2808
|
res.writeHead(404);
|
|
2773
2809
|
res.end();
|
|
@@ -2778,17 +2814,17 @@ async function serveVelixInternal(pathname, req, res, projectRoot) {
|
|
|
2778
2814
|
const componentName = pathname.replace("/__velix/islands/", "").replace(".js", "");
|
|
2779
2815
|
try {
|
|
2780
2816
|
const searchDirs = [
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2817
|
+
path9.join(projectRoot, "components"),
|
|
2818
|
+
path9.join(projectRoot, "app"),
|
|
2819
|
+
path9.join(projectRoot, "islands")
|
|
2784
2820
|
];
|
|
2785
2821
|
let componentPath = "";
|
|
2786
2822
|
for (const dir of searchDirs) {
|
|
2787
|
-
if (!
|
|
2788
|
-
const files =
|
|
2823
|
+
if (!fs8.existsSync(dir)) continue;
|
|
2824
|
+
const files = fs8.readdirSync(dir, { recursive: true });
|
|
2789
2825
|
const found = files.find((f) => f.replace(/\\/g, "/").endsWith(`${componentName}.tsx`) || f.replace(/\\/g, "/").endsWith(`${componentName}.jsx`));
|
|
2790
2826
|
if (found) {
|
|
2791
|
-
componentPath =
|
|
2827
|
+
componentPath = path9.join(dir, found);
|
|
2792
2828
|
break;
|
|
2793
2829
|
}
|
|
2794
2830
|
}
|
|
@@ -2868,32 +2904,32 @@ init_esm_shims();
|
|
|
2868
2904
|
var CacheManager = class {
|
|
2869
2905
|
cache = /* @__PURE__ */ new Map();
|
|
2870
2906
|
tagIndex = /* @__PURE__ */ new Map();
|
|
2871
|
-
set(
|
|
2907
|
+
set(path11, data, tags = []) {
|
|
2872
2908
|
const entry = {
|
|
2873
|
-
path:
|
|
2909
|
+
path: path11,
|
|
2874
2910
|
tags: new Set(tags),
|
|
2875
2911
|
timestamp: Date.now(),
|
|
2876
2912
|
data
|
|
2877
2913
|
};
|
|
2878
|
-
this.cache.set(
|
|
2914
|
+
this.cache.set(path11, entry);
|
|
2879
2915
|
tags.forEach((tag) => {
|
|
2880
2916
|
if (!this.tagIndex.has(tag)) {
|
|
2881
2917
|
this.tagIndex.set(tag, /* @__PURE__ */ new Set());
|
|
2882
2918
|
}
|
|
2883
|
-
this.tagIndex.get(tag).add(
|
|
2919
|
+
this.tagIndex.get(tag).add(path11);
|
|
2884
2920
|
});
|
|
2885
2921
|
}
|
|
2886
|
-
get(
|
|
2887
|
-
const entry = this.cache.get(
|
|
2922
|
+
get(path11) {
|
|
2923
|
+
const entry = this.cache.get(path11);
|
|
2888
2924
|
return entry ? entry.data : null;
|
|
2889
2925
|
}
|
|
2890
|
-
revalidatePath(
|
|
2891
|
-
this.cache.delete(
|
|
2926
|
+
revalidatePath(path11) {
|
|
2927
|
+
this.cache.delete(path11);
|
|
2892
2928
|
}
|
|
2893
2929
|
revalidateTag(tag) {
|
|
2894
2930
|
const paths = this.tagIndex.get(tag);
|
|
2895
2931
|
if (paths) {
|
|
2896
|
-
paths.forEach((
|
|
2932
|
+
paths.forEach((path11) => this.cache.delete(path11));
|
|
2897
2933
|
this.tagIndex.delete(tag);
|
|
2898
2934
|
}
|
|
2899
2935
|
}
|
|
@@ -2901,17 +2937,17 @@ var CacheManager = class {
|
|
|
2901
2937
|
this.cache.clear();
|
|
2902
2938
|
this.tagIndex.clear();
|
|
2903
2939
|
}
|
|
2904
|
-
has(
|
|
2905
|
-
return this.cache.has(
|
|
2940
|
+
has(path11) {
|
|
2941
|
+
return this.cache.has(path11);
|
|
2906
2942
|
}
|
|
2907
2943
|
};
|
|
2908
2944
|
var cacheManager = new CacheManager();
|
|
2909
|
-
function revalidatePath(
|
|
2910
|
-
cacheManager.revalidatePath(
|
|
2945
|
+
function revalidatePath(path11, type = "path") {
|
|
2946
|
+
cacheManager.revalidatePath(path11);
|
|
2911
2947
|
if (typeof global !== "undefined" && global.__VELIX_HMR_SERVER__) {
|
|
2912
2948
|
global.__VELIX_HMR_SERVER__.broadcast(JSON.stringify({
|
|
2913
2949
|
type: "revalidate",
|
|
2914
|
-
path:
|
|
2950
|
+
path: path11,
|
|
2915
2951
|
revalidationType: type
|
|
2916
2952
|
}));
|
|
2917
2953
|
}
|
|
@@ -3179,8 +3215,8 @@ Image.displayName = "Image";
|
|
|
3179
3215
|
// build/index.ts
|
|
3180
3216
|
init_esm_shims();
|
|
3181
3217
|
import esbuild2 from "esbuild";
|
|
3182
|
-
import
|
|
3183
|
-
import
|
|
3218
|
+
import fs9 from "fs";
|
|
3219
|
+
import path10 from "path";
|
|
3184
3220
|
async function build(options = {}) {
|
|
3185
3221
|
const projectRoot = options.projectRoot || process.cwd();
|
|
3186
3222
|
const config = await loadConfig(projectRoot);
|
|
@@ -3199,7 +3235,7 @@ async function build(options = {}) {
|
|
|
3199
3235
|
return;
|
|
3200
3236
|
}
|
|
3201
3237
|
try {
|
|
3202
|
-
const serverOutDir =
|
|
3238
|
+
const serverOutDir = path10.join(outDir, "server");
|
|
3203
3239
|
ensureDir(serverOutDir);
|
|
3204
3240
|
await esbuild2.build({
|
|
3205
3241
|
entryPoints: sourceFiles,
|
|
@@ -3219,10 +3255,10 @@ async function build(options = {}) {
|
|
|
3219
3255
|
process.exit(1);
|
|
3220
3256
|
}
|
|
3221
3257
|
try {
|
|
3222
|
-
const clientOutDir =
|
|
3258
|
+
const clientOutDir = path10.join(outDir, "client");
|
|
3223
3259
|
ensureDir(clientOutDir);
|
|
3224
3260
|
const clientFiles = sourceFiles.filter((f) => {
|
|
3225
|
-
const content =
|
|
3261
|
+
const content = fs9.readFileSync(f, "utf-8");
|
|
3226
3262
|
const firstLine = content.split("\n")[0]?.trim();
|
|
3227
3263
|
return firstLine === "'use client'" || firstLine === '"use client"' || firstLine === "'use island'" || firstLine === '"use island"';
|
|
3228
3264
|
});
|
|
@@ -3248,8 +3284,8 @@ async function build(options = {}) {
|
|
|
3248
3284
|
process.exit(1);
|
|
3249
3285
|
}
|
|
3250
3286
|
const publicDir = resolved.resolvedPublicDir;
|
|
3251
|
-
if (
|
|
3252
|
-
const publicOutDir =
|
|
3287
|
+
if (fs9.existsSync(publicDir)) {
|
|
3288
|
+
const publicOutDir = path10.join(outDir, "public");
|
|
3253
3289
|
ensureDir(publicOutDir);
|
|
3254
3290
|
copyDirRecursive(publicDir, publicOutDir);
|
|
3255
3291
|
logger_default.success("Static assets copied");
|
|
@@ -3263,7 +3299,7 @@ async function build(options = {}) {
|
|
|
3263
3299
|
})),
|
|
3264
3300
|
api: routes.api.map((r) => ({ path: r.path }))
|
|
3265
3301
|
};
|
|
3266
|
-
|
|
3302
|
+
fs9.writeFileSync(path10.join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
3267
3303
|
const elapsed = Date.now() - startTime;
|
|
3268
3304
|
const totalSize = getDirSize(outDir);
|
|
3269
3305
|
logger_default.blank();
|
|
@@ -3281,22 +3317,22 @@ async function build(options = {}) {
|
|
|
3281
3317
|
}
|
|
3282
3318
|
function copyDirRecursive(src, dest) {
|
|
3283
3319
|
ensureDir(dest);
|
|
3284
|
-
const entries =
|
|
3320
|
+
const entries = fs9.readdirSync(src, { withFileTypes: true });
|
|
3285
3321
|
for (const entry of entries) {
|
|
3286
|
-
const srcPath =
|
|
3287
|
-
const destPath =
|
|
3322
|
+
const srcPath = path10.join(src, entry.name);
|
|
3323
|
+
const destPath = path10.join(dest, entry.name);
|
|
3288
3324
|
if (entry.isDirectory()) copyDirRecursive(srcPath, destPath);
|
|
3289
|
-
else
|
|
3325
|
+
else fs9.copyFileSync(srcPath, destPath);
|
|
3290
3326
|
}
|
|
3291
3327
|
}
|
|
3292
3328
|
function getDirSize(dir) {
|
|
3293
3329
|
let size = 0;
|
|
3294
|
-
if (!
|
|
3295
|
-
const entries =
|
|
3330
|
+
if (!fs9.existsSync(dir)) return size;
|
|
3331
|
+
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
3296
3332
|
for (const entry of entries) {
|
|
3297
|
-
const fullPath =
|
|
3333
|
+
const fullPath = path10.join(dir, entry.name);
|
|
3298
3334
|
if (entry.isDirectory()) size += getDirSize(fullPath);
|
|
3299
|
-
else size +=
|
|
3335
|
+
else size += fs9.statSync(fullPath).size;
|
|
3300
3336
|
}
|
|
3301
3337
|
return size;
|
|
3302
3338
|
}
|