@mandujs/core 0.20.2 → 0.20.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mandujs/core",
3
- "version": "0.20.2",
3
+ "version": "0.20.4",
4
4
  "description": "Mandu Framework Core - Spec, Generator, Guard, Runtime",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -84,11 +84,23 @@ export type MCPConnectionStatus =
84
84
  // Constants
85
85
  // ============================================================================
86
86
 
87
+ /**
88
+ * #176: 런타임에 현재 페이지 호스트/포트에서 MCP WebSocket URL을 유추한다.
89
+ * Bun 번들러가 `typeof window`를 컴파일 시 dead-code 제거하므로
90
+ * 함수로 감싸서 런타임 평가를 보장한다.
91
+ */
92
+ function resolveDefaultServerUrl(): string {
93
+ try {
94
+ // eslint-disable-next-line no-restricted-globals
95
+ if (globalThis.document && globalThis.location) {
96
+ return `ws://${globalThis.location.hostname}:${globalThis.location.port}/mcp`;
97
+ }
98
+ } catch { /* SSR / Node / Bun 환경 */ }
99
+ return 'ws://localhost:3333/mcp';
100
+ }
101
+
87
102
  const DEFAULT_OPTIONS: Required<MCPConnectorOptions> = {
88
- // #176: 포트 하드코딩 제거 현재 페이지의 호스트/포트에서 자동 유추
89
- serverUrl: typeof window !== 'undefined'
90
- ? `ws://${window.location.hostname}:${window.location.port}/mcp`
91
- : 'ws://localhost:3333/mcp',
103
+ serverUrl: '', // connect() resolveDefaultServerUrl()로 대체
92
104
  connectionTimeout: 5000,
93
105
  requestTimeout: 30000,
94
106
  // #175: MCP 서버가 없을 수 있으므로 기본 비활성화
@@ -146,7 +158,9 @@ export class MCPConnector {
146
158
  }, this.options.connectionTimeout);
147
159
 
148
160
  try {
149
- this.ws = new WebSocket(this.options.serverUrl);
161
+ // #176: serverUrl이면 런타임에서 현재 페이지 기준으로 유추
162
+ const url = this.options.serverUrl || resolveDefaultServerUrl();
163
+ this.ws = new WebSocket(url);
150
164
 
151
165
  this.ws.onopen = () => {
152
166
  clearTimeout(timeout);
@@ -1021,6 +1021,10 @@ async function handleRequest(req: Request, router: Router, registry: ServerRegis
1021
1021
  if (!result.ok) {
1022
1022
  const errorResponse = errorToResponse(result.error, registry.settings.isDev);
1023
1023
  if (registry.settings.isDev) {
1024
+ // #177: dev 모드 에러 응답도 캐시 방지
1025
+ if (!errorResponse.headers.has("Cache-Control")) {
1026
+ errorResponse.headers.set("Cache-Control", "no-cache, no-store, must-revalidate");
1027
+ }
1024
1028
  const url = new URL(req.url);
1025
1029
  const p = url.pathname;
1026
1030
  if (!p.startsWith("/.mandu/") && !p.startsWith("/__kitchen")) {
@@ -1035,6 +1039,13 @@ async function handleRequest(req: Request, router: Router, registry: ServerRegis
1035
1039
  if (registry.settings.isDev) {
1036
1040
  const url = new URL(req.url);
1037
1041
  const p = url.pathname;
1042
+
1043
+ // #177: dev 모드에서 SSR HTML 응답에 Cache-Control 헤더 추가
1044
+ // 브라우저가 오래된 HTML을 캐시하여 변경사항이 반영 안 되는 문제 방지
1045
+ if (!result.value.headers.has("Cache-Control")) {
1046
+ result.value.headers.set("Cache-Control", "no-cache, no-store, must-revalidate");
1047
+ }
1048
+
1038
1049
  if (!p.startsWith("/.mandu/") && !p.startsWith("/__kitchen")) {
1039
1050
  const elapsed = Date.now() - requestStart;
1040
1051
  const status = result.value.status;