@nine-lab/nine-mu 0.1.348 → 0.1.349
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/dist/nine-mu.js +52 -35
- package/dist/nine-mu.js.map +1 -1
- package/dist/nine-mu.umd.js +1 -1
- package/dist/nine-mu.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/exception/ExceptionHook.js +39 -36
package/package.json
CHANGED
|
@@ -1,44 +1,51 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
// ==========================================
|
|
4
|
-
// 1.
|
|
4
|
+
// 1. 터미널 프롬프트 테마 스타일 (블랙/화이트/그레이 기반)
|
|
5
5
|
// ==========================================
|
|
6
6
|
export const NineExceptionStyles = {
|
|
7
7
|
container: {
|
|
8
8
|
padding: '30px',
|
|
9
9
|
margin: '20px',
|
|
10
|
-
background: '#
|
|
11
|
-
border: '1px solid #
|
|
12
|
-
borderRadius: '
|
|
13
|
-
fontFamily: '
|
|
14
|
-
textAlign: 'left'
|
|
10
|
+
background: '#121314', // 터미널 다크 블랙 배경
|
|
11
|
+
border: '1px solid #343A40', // 소프트한 메탈릭 테두리
|
|
12
|
+
borderRadius: '6px',
|
|
13
|
+
fontFamily: 'Consolas, Monaco, "Courier New", monospace', // 터미널 고정폭 글꼴 우선
|
|
14
|
+
textAlign: 'left',
|
|
15
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.3)' // 터미널 윈도우 입체감
|
|
15
16
|
},
|
|
16
17
|
title: {
|
|
17
|
-
color: '#
|
|
18
|
+
color: '#FFFFFF', // 화이트 타이틀
|
|
18
19
|
marginTop: 0,
|
|
19
|
-
fontSize: '
|
|
20
|
+
fontSize: '16px',
|
|
21
|
+
fontWeight: '600',
|
|
20
22
|
display: 'flex',
|
|
21
23
|
alignItems: 'center',
|
|
22
|
-
gap: '8px'
|
|
24
|
+
gap: '8px',
|
|
25
|
+
borderBottom: '1px solid #2D3139', // 상단 바 구분선 느낌
|
|
26
|
+
paddingBottom: '12px'
|
|
23
27
|
},
|
|
24
28
|
label: {
|
|
25
|
-
margin: '
|
|
29
|
+
margin: '15px 0 8px 0',
|
|
26
30
|
fontWeight: 'bold',
|
|
27
|
-
color: '#
|
|
31
|
+
color: '#A0AEC0', // 프롬프트 서브 텍스트 (연한 그레이)
|
|
32
|
+
fontSize: '13px'
|
|
28
33
|
},
|
|
29
34
|
pre: {
|
|
30
|
-
background: '#
|
|
31
|
-
color: '#
|
|
35
|
+
background: '#1A1C1E', // 코드 블록 내부의 살짝 더 깊은 블랙
|
|
36
|
+
color: '#F8F9FA', // 에러 로그 화이트 출력
|
|
32
37
|
padding: '15px',
|
|
33
|
-
borderRadius: '
|
|
38
|
+
borderRadius: '4px',
|
|
39
|
+
border: '1px solid #2A2D30',
|
|
34
40
|
overflowX: 'auto',
|
|
35
41
|
whiteSpace: 'pre-wrap',
|
|
36
|
-
fontFamily: 'monospace',
|
|
37
|
-
fontSize: '
|
|
42
|
+
fontFamily: 'Consolas, Monaco, monospace',
|
|
43
|
+
fontSize: '13px',
|
|
44
|
+
lineHeight: '1.5'
|
|
38
45
|
},
|
|
39
46
|
footer: {
|
|
40
|
-
marginTop: '
|
|
41
|
-
fontSize: '
|
|
47
|
+
marginTop: '20px',
|
|
48
|
+
fontSize: '13px',
|
|
42
49
|
color: '#718096',
|
|
43
50
|
display: 'flex',
|
|
44
51
|
flexDirection: 'column',
|
|
@@ -46,26 +53,26 @@ export const NineExceptionStyles = {
|
|
|
46
53
|
},
|
|
47
54
|
button: {
|
|
48
55
|
padding: '10px 16px',
|
|
49
|
-
background: '#E53E3E',
|
|
56
|
+
background: '#E53E3E', // 버튼의 고유 아이덴티티 유지 (레드)
|
|
50
57
|
color: '#FFFFFF',
|
|
51
58
|
border: 'none',
|
|
52
|
-
borderRadius: '
|
|
59
|
+
borderRadius: '4px',
|
|
53
60
|
cursor: 'pointer',
|
|
54
61
|
fontWeight: 'bold',
|
|
55
|
-
fontSize: '
|
|
62
|
+
fontSize: '13px',
|
|
56
63
|
alignSelf: 'flex-start',
|
|
57
64
|
transition: 'background 0.2s',
|
|
65
|
+
fontFamily: 'sans-serif' // 버튼 텍스트는 일반 폰트로 가독성 확보
|
|
58
66
|
}
|
|
59
67
|
};
|
|
60
68
|
|
|
61
69
|
// ==========================================
|
|
62
|
-
// 2. 컴포넌트 본문
|
|
70
|
+
// 2. 컴포넌트 본문 (기존 로직 유지)
|
|
63
71
|
// ==========================================
|
|
64
72
|
export class NineExceptionHook extends React.Component {
|
|
65
73
|
|
|
66
74
|
constructor(props) {
|
|
67
75
|
super(props);
|
|
68
|
-
// 관제탑 전송 상태 관리를 위해 정송 단계(idle, sending, success) 추가
|
|
69
76
|
this.state = { hasError: false, error: null, reportStatus: 'idle' };
|
|
70
77
|
this.lastPath = window.location.pathname;
|
|
71
78
|
this.handleLocationChange = this.handleLocationChange.bind(this);
|
|
@@ -79,7 +86,6 @@ export class NineExceptionHook extends React.Component {
|
|
|
79
86
|
componentDidCatch(error, errorInfo) {
|
|
80
87
|
console.error("🚨 [Nine-Library] 본문 렌더링 에러 포착:", error);
|
|
81
88
|
|
|
82
|
-
// 자동 복구 엔진 호출 제거 (버튼 클릭 시 처리로 이관)
|
|
83
89
|
if (this.props.onCatch) {
|
|
84
90
|
this.props.onCatch(error, errorInfo);
|
|
85
91
|
}
|
|
@@ -98,14 +104,13 @@ export class NineExceptionHook extends React.Component {
|
|
|
98
104
|
handleLocationChange() {
|
|
99
105
|
setTimeout(() => {
|
|
100
106
|
if (this.state.hasError && this.lastPath !== window.location.pathname) {
|
|
101
|
-
console.log("
|
|
107
|
+
console.log("[Nine-Library] 페이지 주소 변경 감지 -> 리액트 에러 상태 초기화");
|
|
102
108
|
this.lastPath = window.location.pathname;
|
|
103
109
|
this.setState({ hasError: false, error: null, reportStatus: 'idle' });
|
|
104
110
|
}
|
|
105
111
|
}, 10);
|
|
106
112
|
}
|
|
107
113
|
|
|
108
|
-
// 🚀 버튼 클릭 시 실행될 관제탑 수동 신고 핸들러
|
|
109
114
|
handleReport() {
|
|
110
115
|
if (this.state.reportStatus !== 'idle') return;
|
|
111
116
|
|
|
@@ -116,10 +121,10 @@ export class NineExceptionHook extends React.Component {
|
|
|
116
121
|
if (window.triggerAutoRecovery) {
|
|
117
122
|
window.triggerAutoRecovery(errorMessage);
|
|
118
123
|
} else {
|
|
119
|
-
console.warn("
|
|
124
|
+
console.warn("[Nine-Library] window.triggerAutoRecovery 가 정의되지 않았습니다.");
|
|
120
125
|
}
|
|
121
126
|
this.setState({ reportStatus: 'success' });
|
|
122
|
-
}, 500);
|
|
127
|
+
}, 500);
|
|
123
128
|
}
|
|
124
129
|
|
|
125
130
|
render() {
|
|
@@ -129,23 +134,21 @@ export class NineExceptionHook extends React.Component {
|
|
|
129
134
|
}
|
|
130
135
|
|
|
131
136
|
const errorMessage = this.state.error?.message || String(this.state.error);
|
|
132
|
-
const customStyles = this.props.styles || {};
|
|
137
|
+
const customStyles = this.props.styles || {};
|
|
133
138
|
|
|
134
|
-
// 버튼 텍스트 상태 제어
|
|
135
139
|
let buttonText = '🚀 관제탑에 에러 피드백 전송하기';
|
|
136
140
|
if (this.state.reportStatus === 'sending') buttonText = '⏳ 관제탑 연락 중...';
|
|
137
|
-
if (this.state.reportStatus === 'success') buttonText = '✅ 전송 완료! AI
|
|
141
|
+
if (this.state.reportStatus === 'success') buttonText = '✅ 전송 완료! AI 분석 시작';
|
|
138
142
|
|
|
139
143
|
return React.createElement(
|
|
140
144
|
'div',
|
|
141
145
|
{
|
|
142
146
|
style: { ...NineExceptionStyles.container, ...customStyles.container, ...this.props.containerStyle }
|
|
143
147
|
},
|
|
144
|
-
React.createElement('h3', { style: { ...NineExceptionStyles.title, ...customStyles.title } }, '
|
|
145
|
-
React.createElement('p', { style: { ...NineExceptionStyles.label, ...customStyles.label } }, '
|
|
148
|
+
React.createElement('h3', { style: { ...NineExceptionStyles.title, ...customStyles.title } }, '🤖 [SYSTEM] COMPONENT RENDER ERROR DETECTED'),
|
|
149
|
+
React.createElement('p', { style: { ...NineExceptionStyles.label, ...customStyles.label } }, '$ cat error.log'),
|
|
146
150
|
React.createElement('pre', { style: { ...NineExceptionStyles.pre, ...customStyles.pre } }, errorMessage),
|
|
147
151
|
|
|
148
|
-
// 하단 안내 영역 및 수동 전송 버튼
|
|
149
152
|
React.createElement(
|
|
150
153
|
'div',
|
|
151
154
|
{ style: { ...NineExceptionStyles.footer, ...customStyles.footer } },
|
|
@@ -165,8 +168,8 @@ export class NineExceptionHook extends React.Component {
|
|
|
165
168
|
),
|
|
166
169
|
this.state.reportStatus === 'success' && React.createElement(
|
|
167
170
|
'div',
|
|
168
|
-
{ style: { color: '#
|
|
169
|
-
'
|
|
171
|
+
{ style: { color: '#CBD5E0', fontSize: '13px', marginTop: '5px', fontStyle: 'italic' } },
|
|
172
|
+
'>> AI가 소스 코드를 재수정하는 동안 잠시만 기다려주세요...'
|
|
170
173
|
)
|
|
171
174
|
)
|
|
172
175
|
);
|