@mandujs/core 0.8.0 → 0.8.2
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.ko.md +200 -200
- package/README.md +200 -200
- package/package.json +41 -41
- package/src/bundler/build.ts +36 -8
- package/src/bundler/dev.ts +98 -52
- package/src/client/Link.tsx +209 -209
- package/src/client/hooks.ts +267 -267
- package/src/client/router.ts +387 -387
- package/src/client/serialize.ts +404 -404
- package/src/filling/auth.ts +308 -308
- package/src/filling/context.ts +438 -438
- package/src/filling/filling.ts +306 -306
- package/src/filling/index.ts +21 -21
- package/src/generator/index.ts +3 -3
- package/src/report/index.ts +1 -1
- package/src/runtime/compose.ts +222 -222
- package/src/runtime/index.ts +3 -3
- package/src/runtime/lifecycle.ts +381 -381
- package/src/runtime/ssr.ts +321 -321
- package/src/runtime/trace.ts +144 -144
- package/src/spec/index.ts +3 -3
- package/src/spec/load.ts +76 -76
- package/src/spec/lock.ts +56 -56
package/README.md
CHANGED
|
@@ -1,200 +1,200 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/konamgil/mandu/main/mandu_only_simbol.png" alt="Mandu" width="200" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">@mandujs/core</h1>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<strong>Mandu Framework Core</strong><br/>
|
|
9
|
-
Spec, Generator, Guard, Runtime, Filling
|
|
10
|
-
</p>
|
|
11
|
-
|
|
12
|
-
<p align="center">
|
|
13
|
-
English | <a href="./README.ko.md"><strong>한국어</strong></a>
|
|
14
|
-
</p>
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
bun add @mandujs/core
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
> Typically used through `@mandujs/cli`. Direct usage is for advanced use cases.
|
|
23
|
-
|
|
24
|
-
## Module Structure
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
@mandujs/core
|
|
28
|
-
├── spec/ # Spec schema and loading
|
|
29
|
-
├── generator/ # Code generation
|
|
30
|
-
├── guard/ # Architecture checking and auto-correction
|
|
31
|
-
├── runtime/ # Server and router
|
|
32
|
-
└── report/ # Guard report generation
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Spec Module
|
|
36
|
-
|
|
37
|
-
Route manifest schema definition and loading.
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
import { loadManifest, RoutesManifest, RouteSpec } from "@mandujs/core";
|
|
41
|
-
|
|
42
|
-
// Load and validate manifest
|
|
43
|
-
const result = await loadManifest("spec/routes.manifest.json");
|
|
44
|
-
|
|
45
|
-
if (result.success && result.data) {
|
|
46
|
-
const manifest: RoutesManifest = result.data;
|
|
47
|
-
manifest.routes.forEach((route: RouteSpec) => {
|
|
48
|
-
console.log(route.id, route.pattern, route.kind);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Lock File
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
import { writeLock, readLock } from "@mandujs/core";
|
|
57
|
-
|
|
58
|
-
// Write lock file
|
|
59
|
-
const lock = await writeLock("spec/spec.lock.json", manifest);
|
|
60
|
-
console.log(lock.routesHash);
|
|
61
|
-
|
|
62
|
-
// Read lock file
|
|
63
|
-
const existing = await readLock("spec/spec.lock.json");
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Generator Module
|
|
67
|
-
|
|
68
|
-
Spec-based code generation.
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
import { generateRoutes, GenerateResult } from "@mandujs/core";
|
|
72
|
-
|
|
73
|
-
const result: GenerateResult = await generateRoutes(manifest, "./");
|
|
74
|
-
|
|
75
|
-
console.log("Created:", result.created);
|
|
76
|
-
console.log("Skipped:", result.skipped); // Existing slot files
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Template Functions
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import {
|
|
83
|
-
generateApiHandler,
|
|
84
|
-
generateApiHandlerWithSlot,
|
|
85
|
-
generateSlotLogic,
|
|
86
|
-
generatePageComponent
|
|
87
|
-
} from "@mandujs/core";
|
|
88
|
-
|
|
89
|
-
// Generate API handler
|
|
90
|
-
const code = generateApiHandler(route);
|
|
91
|
-
|
|
92
|
-
// API handler with slot
|
|
93
|
-
const codeWithSlot = generateApiHandlerWithSlot(route);
|
|
94
|
-
|
|
95
|
-
// Slot logic file
|
|
96
|
-
const slotCode = generateSlotLogic(route);
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Guard Module
|
|
100
|
-
|
|
101
|
-
Architecture rule checking and auto-correction.
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
import {
|
|
105
|
-
runGuardCheck,
|
|
106
|
-
runAutoCorrect,
|
|
107
|
-
GuardResult,
|
|
108
|
-
GuardViolation
|
|
109
|
-
} from "@mandujs/core";
|
|
110
|
-
|
|
111
|
-
// Run check
|
|
112
|
-
const result: GuardResult = await runGuardCheck(manifest, "./");
|
|
113
|
-
|
|
114
|
-
if (!result.passed) {
|
|
115
|
-
result.violations.forEach((v: GuardViolation) => {
|
|
116
|
-
console.log(`${v.rule}: ${v.message}`);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// Run auto-correction
|
|
120
|
-
const corrected = await runAutoCorrect(result.violations, manifest, "./");
|
|
121
|
-
console.log("Fixed:", corrected.steps);
|
|
122
|
-
console.log("Remaining violations:", corrected.remainingViolations);
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Guard Rules
|
|
127
|
-
|
|
128
|
-
| Rule ID | Description | Auto-correctable |
|
|
129
|
-
|---------|-------------|------------------|
|
|
130
|
-
| `SPEC_HASH_MISMATCH` | Spec and lock hash mismatch | ✅ |
|
|
131
|
-
| `GENERATED_MANUAL_EDIT` | Manual edit to generated file | ✅ |
|
|
132
|
-
| `HANDLER_NOT_FOUND` | Handler file not found | ❌ |
|
|
133
|
-
| `COMPONENT_NOT_FOUND` | Component file not found | ❌ |
|
|
134
|
-
| `SLOT_NOT_FOUND` | Slot file not found | ✅ |
|
|
135
|
-
|
|
136
|
-
## Runtime Module
|
|
137
|
-
|
|
138
|
-
Server startup and routing.
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
import {
|
|
142
|
-
startServer,
|
|
143
|
-
registerApiHandler,
|
|
144
|
-
registerPageLoader
|
|
145
|
-
} from "@mandujs/core";
|
|
146
|
-
|
|
147
|
-
// Register API handler
|
|
148
|
-
registerApiHandler("getUsers", async (req) => {
|
|
149
|
-
return { users: [] };
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Register page loader
|
|
153
|
-
registerPageLoader("homePage", () => import("./pages/Home"));
|
|
154
|
-
|
|
155
|
-
// Start server
|
|
156
|
-
const server = startServer(manifest, { port: 3000 });
|
|
157
|
-
|
|
158
|
-
// Stop
|
|
159
|
-
server.stop();
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## Report Module
|
|
163
|
-
|
|
164
|
-
Guard result report generation.
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
import { buildGuardReport } from "@mandujs/core";
|
|
168
|
-
|
|
169
|
-
const report = buildGuardReport(guardResult, lockPath);
|
|
170
|
-
console.log(report); // Formatted text report
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Types
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
import type {
|
|
177
|
-
RoutesManifest,
|
|
178
|
-
RouteSpec,
|
|
179
|
-
RouteKind,
|
|
180
|
-
SpecLock,
|
|
181
|
-
GuardResult,
|
|
182
|
-
GuardViolation,
|
|
183
|
-
GenerateResult,
|
|
184
|
-
AutoCorrectResult,
|
|
185
|
-
} from "@mandujs/core";
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Requirements
|
|
189
|
-
|
|
190
|
-
- Bun >= 1.0.0
|
|
191
|
-
- React >= 18.0.0
|
|
192
|
-
- Zod >= 3.0.0
|
|
193
|
-
|
|
194
|
-
## Related Packages
|
|
195
|
-
|
|
196
|
-
- [@mandujs/cli](https://www.npmjs.com/package/@mandujs/cli) - CLI tool
|
|
197
|
-
|
|
198
|
-
## License
|
|
199
|
-
|
|
200
|
-
MIT
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/konamgil/mandu/main/mandu_only_simbol.png" alt="Mandu" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">@mandujs/core</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Mandu Framework Core</strong><br/>
|
|
9
|
+
Spec, Generator, Guard, Runtime, Filling
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
English | <a href="./README.ko.md"><strong>한국어</strong></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun add @mandujs/core
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> Typically used through `@mandujs/cli`. Direct usage is for advanced use cases.
|
|
23
|
+
|
|
24
|
+
## Module Structure
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
@mandujs/core
|
|
28
|
+
├── spec/ # Spec schema and loading
|
|
29
|
+
├── generator/ # Code generation
|
|
30
|
+
├── guard/ # Architecture checking and auto-correction
|
|
31
|
+
├── runtime/ # Server and router
|
|
32
|
+
└── report/ # Guard report generation
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Spec Module
|
|
36
|
+
|
|
37
|
+
Route manifest schema definition and loading.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { loadManifest, RoutesManifest, RouteSpec } from "@mandujs/core";
|
|
41
|
+
|
|
42
|
+
// Load and validate manifest
|
|
43
|
+
const result = await loadManifest("spec/routes.manifest.json");
|
|
44
|
+
|
|
45
|
+
if (result.success && result.data) {
|
|
46
|
+
const manifest: RoutesManifest = result.data;
|
|
47
|
+
manifest.routes.forEach((route: RouteSpec) => {
|
|
48
|
+
console.log(route.id, route.pattern, route.kind);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Lock File
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { writeLock, readLock } from "@mandujs/core";
|
|
57
|
+
|
|
58
|
+
// Write lock file
|
|
59
|
+
const lock = await writeLock("spec/spec.lock.json", manifest);
|
|
60
|
+
console.log(lock.routesHash);
|
|
61
|
+
|
|
62
|
+
// Read lock file
|
|
63
|
+
const existing = await readLock("spec/spec.lock.json");
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Generator Module
|
|
67
|
+
|
|
68
|
+
Spec-based code generation.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { generateRoutes, GenerateResult } from "@mandujs/core";
|
|
72
|
+
|
|
73
|
+
const result: GenerateResult = await generateRoutes(manifest, "./");
|
|
74
|
+
|
|
75
|
+
console.log("Created:", result.created);
|
|
76
|
+
console.log("Skipped:", result.skipped); // Existing slot files
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Template Functions
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import {
|
|
83
|
+
generateApiHandler,
|
|
84
|
+
generateApiHandlerWithSlot,
|
|
85
|
+
generateSlotLogic,
|
|
86
|
+
generatePageComponent
|
|
87
|
+
} from "@mandujs/core";
|
|
88
|
+
|
|
89
|
+
// Generate API handler
|
|
90
|
+
const code = generateApiHandler(route);
|
|
91
|
+
|
|
92
|
+
// API handler with slot
|
|
93
|
+
const codeWithSlot = generateApiHandlerWithSlot(route);
|
|
94
|
+
|
|
95
|
+
// Slot logic file
|
|
96
|
+
const slotCode = generateSlotLogic(route);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Guard Module
|
|
100
|
+
|
|
101
|
+
Architecture rule checking and auto-correction.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import {
|
|
105
|
+
runGuardCheck,
|
|
106
|
+
runAutoCorrect,
|
|
107
|
+
GuardResult,
|
|
108
|
+
GuardViolation
|
|
109
|
+
} from "@mandujs/core";
|
|
110
|
+
|
|
111
|
+
// Run check
|
|
112
|
+
const result: GuardResult = await runGuardCheck(manifest, "./");
|
|
113
|
+
|
|
114
|
+
if (!result.passed) {
|
|
115
|
+
result.violations.forEach((v: GuardViolation) => {
|
|
116
|
+
console.log(`${v.rule}: ${v.message}`);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Run auto-correction
|
|
120
|
+
const corrected = await runAutoCorrect(result.violations, manifest, "./");
|
|
121
|
+
console.log("Fixed:", corrected.steps);
|
|
122
|
+
console.log("Remaining violations:", corrected.remainingViolations);
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Guard Rules
|
|
127
|
+
|
|
128
|
+
| Rule ID | Description | Auto-correctable |
|
|
129
|
+
|---------|-------------|------------------|
|
|
130
|
+
| `SPEC_HASH_MISMATCH` | Spec and lock hash mismatch | ✅ |
|
|
131
|
+
| `GENERATED_MANUAL_EDIT` | Manual edit to generated file | ✅ |
|
|
132
|
+
| `HANDLER_NOT_FOUND` | Handler file not found | ❌ |
|
|
133
|
+
| `COMPONENT_NOT_FOUND` | Component file not found | ❌ |
|
|
134
|
+
| `SLOT_NOT_FOUND` | Slot file not found | ✅ |
|
|
135
|
+
|
|
136
|
+
## Runtime Module
|
|
137
|
+
|
|
138
|
+
Server startup and routing.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import {
|
|
142
|
+
startServer,
|
|
143
|
+
registerApiHandler,
|
|
144
|
+
registerPageLoader
|
|
145
|
+
} from "@mandujs/core";
|
|
146
|
+
|
|
147
|
+
// Register API handler
|
|
148
|
+
registerApiHandler("getUsers", async (req) => {
|
|
149
|
+
return { users: [] };
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Register page loader
|
|
153
|
+
registerPageLoader("homePage", () => import("./pages/Home"));
|
|
154
|
+
|
|
155
|
+
// Start server
|
|
156
|
+
const server = startServer(manifest, { port: 3000 });
|
|
157
|
+
|
|
158
|
+
// Stop
|
|
159
|
+
server.stop();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Report Module
|
|
163
|
+
|
|
164
|
+
Guard result report generation.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import { buildGuardReport } from "@mandujs/core";
|
|
168
|
+
|
|
169
|
+
const report = buildGuardReport(guardResult, lockPath);
|
|
170
|
+
console.log(report); // Formatted text report
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Types
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import type {
|
|
177
|
+
RoutesManifest,
|
|
178
|
+
RouteSpec,
|
|
179
|
+
RouteKind,
|
|
180
|
+
SpecLock,
|
|
181
|
+
GuardResult,
|
|
182
|
+
GuardViolation,
|
|
183
|
+
GenerateResult,
|
|
184
|
+
AutoCorrectResult,
|
|
185
|
+
} from "@mandujs/core";
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Requirements
|
|
189
|
+
|
|
190
|
+
- Bun >= 1.0.0
|
|
191
|
+
- React >= 18.0.0
|
|
192
|
+
- Zod >= 3.0.0
|
|
193
|
+
|
|
194
|
+
## Related Packages
|
|
195
|
+
|
|
196
|
+
- [@mandujs/cli](https://www.npmjs.com/package/@mandujs/cli) - CLI tool
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mandujs/core",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "Mandu Framework Core - Spec, Generator, Guard, Runtime",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./src/index.ts",
|
|
7
|
-
"types": "./src/index.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": "./src/index.ts",
|
|
10
|
-
"./client": "./src/client/index.ts",
|
|
11
|
-
"./*": "./src/*"
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"src/**/*"
|
|
15
|
-
],
|
|
16
|
-
"keywords": [
|
|
17
|
-
"mandu",
|
|
18
|
-
"framework",
|
|
19
|
-
"agent",
|
|
20
|
-
"ai",
|
|
21
|
-
"code-generation"
|
|
22
|
-
],
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/konamgil/mandu.git",
|
|
26
|
-
"directory": "packages/core"
|
|
27
|
-
},
|
|
28
|
-
"author": "konamgil",
|
|
29
|
-
"license": "MIT",
|
|
30
|
-
"publishConfig": {
|
|
31
|
-
"access": "public"
|
|
32
|
-
},
|
|
33
|
-
"engines": {
|
|
34
|
-
"bun": ">=1.0.0"
|
|
35
|
-
},
|
|
36
|
-
"peerDependencies": {
|
|
37
|
-
"react": ">=18.0.0",
|
|
38
|
-
"react-dom": ">=18.0.0",
|
|
39
|
-
"zod": ">=3.0.0"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@mandujs/core",
|
|
3
|
+
"version": "0.8.2",
|
|
4
|
+
"description": "Mandu Framework Core - Spec, Generator, Guard, Runtime",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.ts",
|
|
7
|
+
"types": "./src/index.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.ts",
|
|
10
|
+
"./client": "./src/client/index.ts",
|
|
11
|
+
"./*": "./src/*"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src/**/*"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mandu",
|
|
18
|
+
"framework",
|
|
19
|
+
"agent",
|
|
20
|
+
"ai",
|
|
21
|
+
"code-generation"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/konamgil/mandu.git",
|
|
26
|
+
"directory": "packages/core"
|
|
27
|
+
},
|
|
28
|
+
"author": "konamgil",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"bun": ">=1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"react": ">=18.0.0",
|
|
38
|
+
"react-dom": ">=18.0.0",
|
|
39
|
+
"zod": ">=3.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/bundler/build.ts
CHANGED
|
@@ -62,6 +62,10 @@ function generateRuntimeSource(): string {
|
|
|
62
62
|
* Fresh-style dynamic import architecture
|
|
63
63
|
*/
|
|
64
64
|
|
|
65
|
+
// React 정적 import (Island와 같은 인스턴스 공유)
|
|
66
|
+
import React from 'react';
|
|
67
|
+
import { createRoot } from 'react-dom/client';
|
|
68
|
+
|
|
65
69
|
// Hydrated roots 추적 (unmount용)
|
|
66
70
|
const hydratedRoots = new Map();
|
|
67
71
|
|
|
@@ -134,17 +138,13 @@ async function loadAndHydrate(element, src) {
|
|
|
134
138
|
const { definition } = island;
|
|
135
139
|
const data = getServerData(id);
|
|
136
140
|
|
|
137
|
-
// React
|
|
138
|
-
const { createRoot } = await import('react-dom/client');
|
|
139
|
-
const React = await import('react');
|
|
140
|
-
|
|
141
|
-
// Island 컴포넌트
|
|
141
|
+
// Island 컴포넌트 (정적 import된 React 사용)
|
|
142
142
|
function IslandComponent() {
|
|
143
143
|
const setupResult = definition.setup(data);
|
|
144
144
|
return definition.render(setupResult);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
// Mount
|
|
147
|
+
// Mount (상단에서 import한 createRoot 사용)
|
|
148
148
|
const root = createRoot(element);
|
|
149
149
|
root.render(React.createElement(IslandComponent));
|
|
150
150
|
hydratedRoots.set(id, root);
|
|
@@ -262,6 +262,13 @@ import React, {
|
|
|
262
262
|
Children,
|
|
263
263
|
} from 'react';
|
|
264
264
|
|
|
265
|
+
// JSX Runtime functions (JSX 변환에 필요)
|
|
266
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
267
|
+
import { jsxDEV } from 'react/jsx-dev-runtime';
|
|
268
|
+
|
|
269
|
+
// React internals (ReactDOM이 내부적으로 접근 필요)
|
|
270
|
+
const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
271
|
+
|
|
265
272
|
// Named exports
|
|
266
273
|
export {
|
|
267
274
|
createElement,
|
|
@@ -294,6 +301,11 @@ export {
|
|
|
294
301
|
Component,
|
|
295
302
|
PureComponent,
|
|
296
303
|
Children,
|
|
304
|
+
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
|
|
305
|
+
// JSX Runtime exports
|
|
306
|
+
jsx,
|
|
307
|
+
jsxs,
|
|
308
|
+
jsxDEV,
|
|
297
309
|
};
|
|
298
310
|
|
|
299
311
|
// Default export
|
|
@@ -364,8 +376,9 @@ function generateJsxRuntimeShimSource(): string {
|
|
|
364
376
|
/**
|
|
365
377
|
* Mandu JSX Runtime Shim (Generated)
|
|
366
378
|
* Production JSX 변환용
|
|
379
|
+
* 순환 참조 방지: 'react'에서 import (import map이 _react.js로 매핑)
|
|
367
380
|
*/
|
|
368
|
-
import { jsx, jsxs, Fragment } from 'react
|
|
381
|
+
import { jsx, jsxs, Fragment } from 'react';
|
|
369
382
|
|
|
370
383
|
// Named exports
|
|
371
384
|
export { jsx, jsxs, Fragment };
|
|
@@ -384,8 +397,9 @@ function generateJsxDevRuntimeShimSource(): string {
|
|
|
384
397
|
/**
|
|
385
398
|
* Mandu JSX Dev Runtime Shim (Generated)
|
|
386
399
|
* Development JSX 변환용
|
|
400
|
+
* 순환 참조 방지: 'react'에서 import (import map이 _react.js로 매핑)
|
|
387
401
|
*/
|
|
388
|
-
import { jsxDEV, Fragment } from 'react
|
|
402
|
+
import { jsxDEV, Fragment } from 'react';
|
|
389
403
|
|
|
390
404
|
// Named exports
|
|
391
405
|
export { jsxDEV, Fragment };
|
|
@@ -733,6 +747,19 @@ async function buildVendorShims(
|
|
|
733
747
|
try {
|
|
734
748
|
await Bun.write(srcPath, shim.source);
|
|
735
749
|
|
|
750
|
+
// _react.js와 jsx-runtime들은 완전히 번들링 (external 없음)
|
|
751
|
+
// _react-dom*, jsx-runtime은 react를 external로 처리하여 동일한 React 인스턴스 공유
|
|
752
|
+
// jsx-runtime은 Fragment를 react에서 가져오므로 react만 external
|
|
753
|
+
let shimExternal: string[] = [];
|
|
754
|
+
if (shim.name === "_react-dom" || shim.name === "_react-dom-client") {
|
|
755
|
+
shimExternal = ["react"];
|
|
756
|
+
} else if (shim.name === "_jsx-runtime" || shim.name === "_jsx-dev-runtime") {
|
|
757
|
+
// jsx-runtime은 react를 external로 (Fragment 때문에),
|
|
758
|
+
// 하지만 react/jsx-runtime은 번들링되어야 함
|
|
759
|
+
shimExternal = ["react"];
|
|
760
|
+
}
|
|
761
|
+
// _react.js는 external 없이 React 전체를 번들링
|
|
762
|
+
|
|
736
763
|
const result = await Bun.build({
|
|
737
764
|
entrypoints: [srcPath],
|
|
738
765
|
outdir: outDir,
|
|
@@ -740,6 +767,7 @@ async function buildVendorShims(
|
|
|
740
767
|
minify: options.minify ?? process.env.NODE_ENV === "production",
|
|
741
768
|
sourcemap: options.sourcemap ? "external" : "none",
|
|
742
769
|
target: "browser",
|
|
770
|
+
external: shimExternal,
|
|
743
771
|
define: {
|
|
744
772
|
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
|
|
745
773
|
...options.define,
|