@mandujs/cli 0.4.0 → 0.4.1
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/package.json +40 -40
- package/src/commands/dev.ts +76 -11
- package/src/main.ts +0 -0
package/package.json
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mandujs/cli",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Agent-Native Fullstack Framework - 에이전트가 코딩해도 아키텍처가 무너지지 않는 개발 OS",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./src/main.ts",
|
|
7
|
-
"bin": {
|
|
8
|
-
"mandu": "./src/main.ts"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"src/**/*",
|
|
12
|
-
"templates/**/*"
|
|
13
|
-
],
|
|
14
|
-
"keywords": [
|
|
15
|
-
"ai",
|
|
16
|
-
"agent",
|
|
17
|
-
"framework",
|
|
18
|
-
"fullstack",
|
|
19
|
-
"bun",
|
|
20
|
-
"typescript",
|
|
21
|
-
"react",
|
|
22
|
-
"ssr",
|
|
23
|
-
"code-generation"
|
|
24
|
-
],
|
|
25
|
-
"repository": {
|
|
26
|
-
"type": "git",
|
|
27
|
-
"url": "https://github.com/konamgil/mandu.git"
|
|
28
|
-
},
|
|
29
|
-
"author": "konamgil",
|
|
30
|
-
"license": "MIT",
|
|
31
|
-
"publishConfig": {
|
|
32
|
-
"access": "public"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"@mandujs/core": "^0.4.
|
|
36
|
-
},
|
|
37
|
-
"engines": {
|
|
38
|
-
"bun": ">=1.0.0"
|
|
39
|
-
}
|
|
40
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@mandujs/cli",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "Agent-Native Fullstack Framework - 에이전트가 코딩해도 아키텍처가 무너지지 않는 개발 OS",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/main.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mandu": "./src/main.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src/**/*",
|
|
12
|
+
"templates/**/*"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"ai",
|
|
16
|
+
"agent",
|
|
17
|
+
"framework",
|
|
18
|
+
"fullstack",
|
|
19
|
+
"bun",
|
|
20
|
+
"typescript",
|
|
21
|
+
"react",
|
|
22
|
+
"ssr",
|
|
23
|
+
"code-generation"
|
|
24
|
+
],
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/konamgil/mandu.git"
|
|
28
|
+
},
|
|
29
|
+
"author": "konamgil",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@mandujs/core": "^0.4.1"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"bun": ">=1.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/commands/dev.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
loadManifest,
|
|
3
|
+
startServer,
|
|
4
|
+
registerApiHandler,
|
|
5
|
+
registerPageLoader,
|
|
6
|
+
startDevBundler,
|
|
7
|
+
createHMRServer,
|
|
8
|
+
needsHydration,
|
|
9
|
+
} from "@mandujs/core";
|
|
2
10
|
import { resolveFromCwd } from "../util/fs";
|
|
3
11
|
import path from "path";
|
|
4
12
|
|
|
5
13
|
export interface DevOptions {
|
|
6
14
|
port?: number;
|
|
15
|
+
/** HMR 비활성화 */
|
|
16
|
+
noHmr?: boolean;
|
|
7
17
|
}
|
|
8
18
|
|
|
9
19
|
export async function dev(options: DevOptions = {}): Promise<void> {
|
|
@@ -21,9 +31,11 @@ export async function dev(options: DevOptions = {}): Promise<void> {
|
|
|
21
31
|
process.exit(1);
|
|
22
32
|
}
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
const manifest = result.data;
|
|
35
|
+
console.log(`✅ Spec 로드 완료: ${manifest.routes.length}개 라우트`);
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
// 핸들러 등록
|
|
38
|
+
for (const route of manifest.routes) {
|
|
27
39
|
if (route.kind === "api") {
|
|
28
40
|
const modulePath = path.resolve(rootDir, route.module);
|
|
29
41
|
try {
|
|
@@ -36,7 +48,8 @@ export async function dev(options: DevOptions = {}): Promise<void> {
|
|
|
36
48
|
} else if (route.kind === "page" && route.componentModule) {
|
|
37
49
|
const componentPath = path.resolve(rootDir, route.componentModule);
|
|
38
50
|
registerPageLoader(route.id, () => import(componentPath));
|
|
39
|
-
|
|
51
|
+
const isIsland = needsHydration(route);
|
|
52
|
+
console.log(` 📄 Page: ${route.pattern} -> ${route.id}${isIsland ? " 🏝️" : ""}`);
|
|
40
53
|
}
|
|
41
54
|
}
|
|
42
55
|
|
|
@@ -44,17 +57,69 @@ export async function dev(options: DevOptions = {}): Promise<void> {
|
|
|
44
57
|
|
|
45
58
|
const port = options.port || Number(process.env.PORT) || 3000;
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
// HMR 서버 시작 (클라이언트 슬롯이 있는 경우)
|
|
61
|
+
let hmrServer: ReturnType<typeof createHMRServer> | null = null;
|
|
62
|
+
let devBundler: Awaited<ReturnType<typeof startDevBundler>> | null = null;
|
|
48
63
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
const hasIslands = manifest.routes.some(
|
|
65
|
+
(r) => r.kind === "page" && r.clientModule && needsHydration(r)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (hasIslands && !options.noHmr) {
|
|
69
|
+
// HMR 서버 시작
|
|
70
|
+
hmrServer = createHMRServer(port);
|
|
71
|
+
|
|
72
|
+
// Dev 번들러 시작 (파일 감시)
|
|
73
|
+
devBundler = await startDevBundler({
|
|
74
|
+
rootDir,
|
|
75
|
+
manifest,
|
|
76
|
+
onRebuild: (result) => {
|
|
77
|
+
if (result.success) {
|
|
78
|
+
hmrServer?.broadcast({
|
|
79
|
+
type: "island-update",
|
|
80
|
+
data: {
|
|
81
|
+
routeId: result.routeId,
|
|
82
|
+
timestamp: Date.now(),
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
hmrServer?.broadcast({
|
|
87
|
+
type: "error",
|
|
88
|
+
data: {
|
|
89
|
+
routeId: result.routeId,
|
|
90
|
+
message: result.error,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
onError: (error, routeId) => {
|
|
96
|
+
hmrServer?.broadcast({
|
|
97
|
+
type: "error",
|
|
98
|
+
data: {
|
|
99
|
+
routeId,
|
|
100
|
+
message: error.message,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 메인 서버 시작
|
|
108
|
+
const server = startServer(manifest, {
|
|
109
|
+
port,
|
|
110
|
+
isDev: true,
|
|
111
|
+
hmrPort: hmrServer ? port : undefined,
|
|
53
112
|
});
|
|
54
113
|
|
|
55
|
-
|
|
114
|
+
// 정리 함수
|
|
115
|
+
const cleanup = () => {
|
|
56
116
|
console.log("\n🛑 서버 종료 중...");
|
|
57
117
|
server.stop();
|
|
118
|
+
devBundler?.close();
|
|
119
|
+
hmrServer?.close();
|
|
58
120
|
process.exit(0);
|
|
59
|
-
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
process.on("SIGINT", cleanup);
|
|
124
|
+
process.on("SIGTERM", cleanup);
|
|
60
125
|
}
|
package/src/main.ts
CHANGED
|
File without changes
|