@mandujs/core 0.7.1 → 0.7.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/package.json +1 -1
- package/src/bundler/build.ts +11 -5
- package/src/filling/auth.ts +40 -40
- package/src/filling/context.ts +438 -464
- package/src/filling/filling.ts +252 -552
- package/src/filling/index.ts +21 -21
- package/src/filling/tmpclaude-2f8d-cwd +1 -0
- package/src/filling/tmpclaude-2fc1-cwd +1 -0
- package/src/filling/tmpclaude-59ee-cwd +1 -0
- package/src/filling/tmpclaude-7608-cwd +1 -0
- package/src/filling/tmpclaude-a102-cwd +1 -0
- package/src/filling/tmpclaude-bf2c-cwd +1 -0
- package/src/filling/tmpclaude-fb5a-cwd +1 -0
- package/src/runtime/index.ts +3 -2
- package/src/runtime/lifecycle.ts +25 -4
- package/src/runtime/ssr.ts +315 -313
- package/src/runtime/tmpclaude-1f31-cwd +1 -0
- package/src/runtime/tmpclaude-8527-cwd +1 -0
- package/src/runtime/tmpclaude-e62c-cwd +1 -0
- package/src/runtime/trace.ts +85 -0
package/src/runtime/ssr.ts
CHANGED
|
@@ -1,313 +1,315 @@
|
|
|
1
|
-
import { renderToString } from "react-dom/server";
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.replace(
|
|
40
|
-
.replace(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
</
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
${
|
|
175
|
-
${
|
|
176
|
-
${
|
|
177
|
-
${
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
var
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
1
|
+
import { renderToString } from "react-dom/server";
|
|
2
|
+
import { serializeProps } from "../client/serialize";
|
|
3
|
+
import type { ReactElement } from "react";
|
|
4
|
+
import type { BundleManifest } from "../bundler/types";
|
|
5
|
+
import type { HydrationConfig, HydrationPriority } from "../spec/schema";
|
|
6
|
+
|
|
7
|
+
export interface SSROptions {
|
|
8
|
+
title?: string;
|
|
9
|
+
lang?: string;
|
|
10
|
+
/** 서버에서 로드한 데이터 (클라이언트로 전달) */
|
|
11
|
+
serverData?: Record<string, unknown>;
|
|
12
|
+
/** Hydration 설정 */
|
|
13
|
+
hydration?: HydrationConfig;
|
|
14
|
+
/** 번들 매니페스트 */
|
|
15
|
+
bundleManifest?: BundleManifest;
|
|
16
|
+
/** 라우트 ID (island 식별용) */
|
|
17
|
+
routeId?: string;
|
|
18
|
+
/** 추가 head 태그 */
|
|
19
|
+
headTags?: string;
|
|
20
|
+
/** 추가 body 끝 태그 */
|
|
21
|
+
bodyEndTags?: string;
|
|
22
|
+
/** 개발 모드 여부 */
|
|
23
|
+
isDev?: boolean;
|
|
24
|
+
/** HMR 포트 (개발 모드에서 사용) */
|
|
25
|
+
hmrPort?: number;
|
|
26
|
+
/** Client-side Routing 활성화 여부 */
|
|
27
|
+
enableClientRouter?: boolean;
|
|
28
|
+
/** 라우트 패턴 (Client-side Routing용) */
|
|
29
|
+
routePattern?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* SSR 데이터를 안전하게 직렬화 (Fresh 스타일 고급 직렬화)
|
|
34
|
+
* Date, Map, Set, URL, RegExp, BigInt, 순환참조 지원
|
|
35
|
+
*/
|
|
36
|
+
function serializeServerData(data: Record<string, unknown>): string {
|
|
37
|
+
// serializeProps로 고급 직렬화 (Date, Map, Set 등 지원)
|
|
38
|
+
const json = serializeProps(data)
|
|
39
|
+
.replace(/</g, "\\u003c")
|
|
40
|
+
.replace(/>/g, "\\u003e")
|
|
41
|
+
.replace(/&/g, "\\u0026")
|
|
42
|
+
.replace(/'/g, "\\u0027");
|
|
43
|
+
|
|
44
|
+
return `<script id="__MANDU_DATA__" type="application/json">${json}</script>
|
|
45
|
+
<script>window.__MANDU_DATA_RAW__ = document.getElementById('__MANDU_DATA__').textContent;</script>`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Import map 생성 (bare specifier 해결용)
|
|
50
|
+
*/
|
|
51
|
+
function generateImportMap(manifest: BundleManifest): string {
|
|
52
|
+
if (!manifest.importMap || Object.keys(manifest.importMap.imports).length === 0) {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const importMapJson = JSON.stringify(manifest.importMap, null, 2);
|
|
57
|
+
return `<script type="importmap">${importMapJson}</script>`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Hydration 스크립트 태그 생성
|
|
62
|
+
*/
|
|
63
|
+
function generateHydrationScripts(
|
|
64
|
+
routeId: string,
|
|
65
|
+
manifest: BundleManifest
|
|
66
|
+
): string {
|
|
67
|
+
const scripts: string[] = [];
|
|
68
|
+
|
|
69
|
+
// Import map 먼저 (반드시 module scripts 전에 위치해야 함)
|
|
70
|
+
const importMap = generateImportMap(manifest);
|
|
71
|
+
if (importMap) {
|
|
72
|
+
scripts.push(importMap);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Runtime 로드
|
|
76
|
+
if (manifest.shared.runtime) {
|
|
77
|
+
scripts.push(`<script type="module" src="${manifest.shared.runtime}"></script>`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Island 번들 로드
|
|
81
|
+
const bundle = manifest.bundles[routeId];
|
|
82
|
+
if (bundle) {
|
|
83
|
+
// Preload (선택적)
|
|
84
|
+
scripts.push(`<link rel="modulepreload" href="${bundle.js}">`);
|
|
85
|
+
scripts.push(`<script type="module" src="${bundle.js}"></script>`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return scripts.join("\n");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Island 래퍼로 컨텐츠 감싸기
|
|
93
|
+
*/
|
|
94
|
+
export function wrapWithIsland(
|
|
95
|
+
content: string,
|
|
96
|
+
routeId: string,
|
|
97
|
+
priority: HydrationPriority = "visible"
|
|
98
|
+
): string {
|
|
99
|
+
return `<div data-mandu-island="${routeId}" data-mandu-priority="${priority}">${content}</div>`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function renderToHTML(element: ReactElement, options: SSROptions = {}): string {
|
|
103
|
+
const {
|
|
104
|
+
title = "Mandu App",
|
|
105
|
+
lang = "ko",
|
|
106
|
+
serverData,
|
|
107
|
+
hydration,
|
|
108
|
+
bundleManifest,
|
|
109
|
+
routeId,
|
|
110
|
+
headTags = "",
|
|
111
|
+
bodyEndTags = "",
|
|
112
|
+
isDev = false,
|
|
113
|
+
hmrPort,
|
|
114
|
+
enableClientRouter = false,
|
|
115
|
+
routePattern,
|
|
116
|
+
} = options;
|
|
117
|
+
|
|
118
|
+
let content = renderToString(element);
|
|
119
|
+
|
|
120
|
+
// Island 래퍼 적용 (hydration 필요 시)
|
|
121
|
+
const needsHydration =
|
|
122
|
+
hydration && hydration.strategy !== "none" && routeId && bundleManifest;
|
|
123
|
+
|
|
124
|
+
if (needsHydration) {
|
|
125
|
+
content = wrapWithIsland(content, routeId, hydration.priority);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 서버 데이터 스크립트
|
|
129
|
+
let dataScript = "";
|
|
130
|
+
if (serverData && routeId) {
|
|
131
|
+
const wrappedData = {
|
|
132
|
+
[routeId]: {
|
|
133
|
+
serverData,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
dataScript = serializeServerData(wrappedData);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Client-side Routing: 라우트 정보 주입
|
|
141
|
+
let routeScript = "";
|
|
142
|
+
if (enableClientRouter && routeId) {
|
|
143
|
+
routeScript = generateRouteScript(routeId, routePattern || "", serverData);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Hydration 스크립트
|
|
147
|
+
let hydrationScripts = "";
|
|
148
|
+
if (needsHydration && bundleManifest) {
|
|
149
|
+
hydrationScripts = generateHydrationScripts(routeId, bundleManifest);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Client-side Router 스크립트
|
|
153
|
+
let routerScript = "";
|
|
154
|
+
if (enableClientRouter && bundleManifest) {
|
|
155
|
+
routerScript = generateClientRouterScript(bundleManifest);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// HMR 스크립트 (개발 모드)
|
|
159
|
+
let hmrScript = "";
|
|
160
|
+
if (isDev && hmrPort) {
|
|
161
|
+
hmrScript = generateHMRScript(hmrPort);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return `<!doctype html>
|
|
165
|
+
<html lang="${lang}">
|
|
166
|
+
<head>
|
|
167
|
+
<meta charset="UTF-8">
|
|
168
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
169
|
+
<title>${title}</title>
|
|
170
|
+
${headTags}
|
|
171
|
+
</head>
|
|
172
|
+
<body>
|
|
173
|
+
<div id="root">${content}</div>
|
|
174
|
+
${dataScript}
|
|
175
|
+
${routeScript}
|
|
176
|
+
${hydrationScripts}
|
|
177
|
+
${routerScript}
|
|
178
|
+
${hmrScript}
|
|
179
|
+
${bodyEndTags}
|
|
180
|
+
</body>
|
|
181
|
+
</html>`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Client-side Routing: 현재 라우트 정보 스크립트 생성
|
|
186
|
+
*/
|
|
187
|
+
function generateRouteScript(
|
|
188
|
+
routeId: string,
|
|
189
|
+
pattern: string,
|
|
190
|
+
serverData?: Record<string, unknown>
|
|
191
|
+
): string {
|
|
192
|
+
const routeInfo = {
|
|
193
|
+
id: routeId,
|
|
194
|
+
pattern,
|
|
195
|
+
params: extractParamsFromUrl(pattern),
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const json = JSON.stringify(routeInfo)
|
|
199
|
+
.replace(/</g, "\\u003c")
|
|
200
|
+
.replace(/>/g, "\\u003e");
|
|
201
|
+
|
|
202
|
+
return `<script>window.__MANDU_ROUTE__ = ${json};</script>`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* URL 패턴에서 파라미터 추출 (클라이언트에서 사용)
|
|
207
|
+
*/
|
|
208
|
+
function extractParamsFromUrl(pattern: string): Record<string, string> {
|
|
209
|
+
// 서버에서는 실제 params를 전달받으므로 빈 객체 반환
|
|
210
|
+
// 실제 params는 serverData나 별도 전달
|
|
211
|
+
return {};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Client-side Router 스크립트 로드
|
|
216
|
+
*/
|
|
217
|
+
function generateClientRouterScript(manifest: BundleManifest): string {
|
|
218
|
+
// Import map 먼저 (이미 hydration에서 추가되었을 수 있음)
|
|
219
|
+
const scripts: string[] = [];
|
|
220
|
+
|
|
221
|
+
// 라우터 번들이 있으면 로드
|
|
222
|
+
if (manifest.shared?.router) {
|
|
223
|
+
scripts.push(`<script type="module" src="${manifest.shared.router}"></script>`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return scripts.join("\n");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* HMR 스크립트 생성
|
|
231
|
+
*/
|
|
232
|
+
function generateHMRScript(port: number): string {
|
|
233
|
+
const hmrPort = port + 1;
|
|
234
|
+
return `<script>
|
|
235
|
+
(function() {
|
|
236
|
+
var ws = null;
|
|
237
|
+
var reconnectAttempts = 0;
|
|
238
|
+
var maxReconnectAttempts = 10;
|
|
239
|
+
|
|
240
|
+
function connect() {
|
|
241
|
+
try {
|
|
242
|
+
ws = new WebSocket('ws://localhost:${hmrPort}');
|
|
243
|
+
ws.onopen = function() {
|
|
244
|
+
console.log('[Mandu HMR] Connected');
|
|
245
|
+
reconnectAttempts = 0;
|
|
246
|
+
};
|
|
247
|
+
ws.onmessage = function(e) {
|
|
248
|
+
try {
|
|
249
|
+
var msg = JSON.parse(e.data);
|
|
250
|
+
if (msg.type === 'reload' || msg.type === 'island-update') {
|
|
251
|
+
console.log('[Mandu HMR] Reloading...');
|
|
252
|
+
location.reload();
|
|
253
|
+
} else if (msg.type === 'error') {
|
|
254
|
+
console.error('[Mandu HMR] Build error:', msg.data?.message);
|
|
255
|
+
}
|
|
256
|
+
} catch(err) {}
|
|
257
|
+
};
|
|
258
|
+
ws.onclose = function() {
|
|
259
|
+
if (reconnectAttempts < maxReconnectAttempts) {
|
|
260
|
+
reconnectAttempts++;
|
|
261
|
+
setTimeout(connect, 1000 * reconnectAttempts);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
} catch(err) {
|
|
265
|
+
setTimeout(connect, 1000);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
connect();
|
|
269
|
+
})();
|
|
270
|
+
</script>`;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function createHTMLResponse(html: string, status: number = 200): Response {
|
|
274
|
+
return new Response(html, {
|
|
275
|
+
status,
|
|
276
|
+
headers: {
|
|
277
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function renderSSR(element: ReactElement, options: SSROptions = {}): Response {
|
|
283
|
+
const html = renderToHTML(element, options);
|
|
284
|
+
return createHTMLResponse(html);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Hydration이 포함된 SSR 렌더링
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* const response = await renderWithHydration(
|
|
293
|
+
* <TodoList todos={todos} />,
|
|
294
|
+
* {
|
|
295
|
+
* title: "할일 목록",
|
|
296
|
+
* routeId: "todos",
|
|
297
|
+
* serverData: { todos },
|
|
298
|
+
* hydration: { strategy: "island", priority: "visible" },
|
|
299
|
+
* bundleManifest,
|
|
300
|
+
* }
|
|
301
|
+
* );
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
export async function renderWithHydration(
|
|
305
|
+
element: ReactElement,
|
|
306
|
+
options: SSROptions & {
|
|
307
|
+
routeId: string;
|
|
308
|
+
serverData: Record<string, unknown>;
|
|
309
|
+
hydration: HydrationConfig;
|
|
310
|
+
bundleManifest: BundleManifest;
|
|
311
|
+
}
|
|
312
|
+
): Promise<Response> {
|
|
313
|
+
const html = renderToHTML(element, options);
|
|
314
|
+
return createHTMLResponse(html);
|
|
315
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/c/Users/LamySolution/workspace/mandu/packages/core/src/runtime
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/c/Users/LamySolution/workspace/mandu/packages/core/src/runtime
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/c/Users/LamySolution/workspace/mandu/packages/core/src/runtime
|