@vistagenic/vista 0.2.4 → 0.2.6
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/bin/build-rsc.js +134 -39
- package/dist/bin/build.js +39 -55
- package/dist/bin/dev-error-overlay-snippet.d.ts +5 -0
- package/dist/bin/dev-error-overlay-snippet.js +562 -0
- package/dist/bin/devtools-indicator-snippet.d.ts +5 -0
- package/dist/bin/devtools-indicator-snippet.js +368 -0
- package/dist/build/rsc/server-manifest.js +2 -2
- package/dist/dev-error.d.ts +1 -2
- package/dist/dev-error.js +867 -346
- package/dist/server/engine.js +17 -4
- package/dist/server/rsc-engine.js +126 -5
- package/dist/server/static-generator.js +97 -14
- package/package.json +2 -3
package/dist/dev-error.js
CHANGED
|
@@ -11,216 +11,324 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
11
11
|
/**
|
|
12
12
|
* Vista Error Overlay
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* Uses inline styles and vanilla JS for interactivity.
|
|
14
|
+
* Standalone dev error UI with Next.js-style pagination and controls.
|
|
16
15
|
*/
|
|
17
16
|
const react_1 = __importDefault(require("react"));
|
|
18
17
|
const constants_1 = require("./constants");
|
|
19
18
|
// ============================================================================
|
|
20
|
-
//
|
|
19
|
+
// Styles + runtime helpers
|
|
21
20
|
// ============================================================================
|
|
22
|
-
const OVERLAY_STYLES = `
|
|
23
|
-
* { box-sizing: border-box;
|
|
24
|
-
body {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
background:
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
.vista-error-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
.vista-error-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
.vista-error-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
border-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
border: 1px solid
|
|
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
|
-
font-size: 11px;
|
|
144
|
-
font-weight:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
font-size: 12px;
|
|
160
|
-
color:
|
|
161
|
-
}
|
|
162
|
-
.vista-error-
|
|
163
|
-
display:
|
|
164
|
-
align-items: center;
|
|
165
|
-
gap:
|
|
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
|
-
|
|
21
|
+
const OVERLAY_STYLES = `
|
|
22
|
+
* { box-sizing: border-box; }
|
|
23
|
+
html, body {
|
|
24
|
+
margin: 0;
|
|
25
|
+
min-height: 100%;
|
|
26
|
+
background: #0c0d10;
|
|
27
|
+
color: #e8ebf1;
|
|
28
|
+
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
29
|
+
}
|
|
30
|
+
body {
|
|
31
|
+
line-height: 1.45;
|
|
32
|
+
}
|
|
33
|
+
.vista-error-page-root {
|
|
34
|
+
min-height: 100vh;
|
|
35
|
+
position: relative;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
padding: 24px;
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
}
|
|
42
|
+
.vista-error-page-root[data-embedded='true'] {
|
|
43
|
+
position: fixed;
|
|
44
|
+
inset: 0;
|
|
45
|
+
z-index: 2147483646;
|
|
46
|
+
}
|
|
47
|
+
.vista-error-backdrop {
|
|
48
|
+
position: absolute;
|
|
49
|
+
inset: 0;
|
|
50
|
+
background: radial-gradient(circle at top, rgba(255, 89, 60, 0.22), rgba(10, 11, 15, 0.94) 44%);
|
|
51
|
+
backdrop-filter: blur(5px);
|
|
52
|
+
}
|
|
53
|
+
.vista-error-panel {
|
|
54
|
+
position: relative;
|
|
55
|
+
width: min(980px, 100%);
|
|
56
|
+
max-height: min(86vh, 860px);
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
border-radius: 16px;
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
border: 1px solid rgba(255, 255, 255, 0.14);
|
|
62
|
+
background: linear-gradient(180deg, rgba(24, 27, 33, 0.97), rgba(9, 11, 15, 0.98));
|
|
63
|
+
box-shadow: 0 34px 92px rgba(0, 0, 0, 0.54);
|
|
64
|
+
animation: vista-overlay-in 170ms ease;
|
|
65
|
+
}
|
|
66
|
+
.vista-error-header {
|
|
67
|
+
display: flex;
|
|
68
|
+
justify-content: space-between;
|
|
69
|
+
align-items: flex-start;
|
|
70
|
+
gap: 14px;
|
|
71
|
+
padding: 15px 17px;
|
|
72
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
|
|
73
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0));
|
|
74
|
+
}
|
|
75
|
+
.vista-error-head-left {
|
|
76
|
+
min-width: 0;
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
gap: 8px;
|
|
80
|
+
}
|
|
81
|
+
.vista-error-top-row {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
gap: 10px;
|
|
85
|
+
}
|
|
86
|
+
.vista-error-badge {
|
|
87
|
+
display: inline-flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: 7px;
|
|
90
|
+
height: 24px;
|
|
91
|
+
padding: 0 10px;
|
|
92
|
+
border-radius: 999px;
|
|
93
|
+
border: 1px solid rgba(248, 113, 113, 0.48);
|
|
94
|
+
background: rgba(248, 113, 113, 0.14);
|
|
95
|
+
color: #fecaca;
|
|
96
|
+
font-size: 11px;
|
|
97
|
+
font-weight: 700;
|
|
98
|
+
letter-spacing: 0.07em;
|
|
99
|
+
text-transform: uppercase;
|
|
100
|
+
white-space: nowrap;
|
|
101
|
+
}
|
|
102
|
+
.vista-error-badge-dot {
|
|
103
|
+
width: 7px;
|
|
104
|
+
height: 7px;
|
|
105
|
+
border-radius: 999px;
|
|
106
|
+
background: #f87171;
|
|
107
|
+
box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.24);
|
|
108
|
+
}
|
|
109
|
+
.vista-error-pagination {
|
|
110
|
+
display: inline-flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
gap: 6px;
|
|
113
|
+
padding: 2px 3px;
|
|
114
|
+
border-radius: 999px;
|
|
115
|
+
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
116
|
+
background: rgba(255, 255, 255, 0.04);
|
|
117
|
+
}
|
|
118
|
+
.vista-error-page-btn {
|
|
119
|
+
width: 22px;
|
|
120
|
+
height: 22px;
|
|
121
|
+
display: inline-flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
border: none;
|
|
125
|
+
border-radius: 999px;
|
|
126
|
+
background: rgba(255, 255, 255, 0.13);
|
|
127
|
+
color: #f8fafc;
|
|
128
|
+
font-size: 11px;
|
|
129
|
+
line-height: 1;
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
}
|
|
132
|
+
.vista-error-page-btn:disabled {
|
|
133
|
+
opacity: 0.35;
|
|
134
|
+
cursor: not-allowed;
|
|
135
|
+
}
|
|
136
|
+
.vista-error-page-btn:not(:disabled):hover {
|
|
137
|
+
background: rgba(255, 255, 255, 0.24);
|
|
138
|
+
}
|
|
139
|
+
.vista-error-page-count {
|
|
140
|
+
min-width: 56px;
|
|
141
|
+
text-align: center;
|
|
142
|
+
font-size: 11px;
|
|
143
|
+
font-weight: 630;
|
|
144
|
+
color: rgba(241, 245, 249, 0.95);
|
|
145
|
+
font-variant-numeric: tabular-nums;
|
|
146
|
+
}
|
|
147
|
+
.vista-error-title {
|
|
148
|
+
margin: 0;
|
|
149
|
+
font-size: 18px;
|
|
150
|
+
line-height: 1.32;
|
|
151
|
+
font-weight: 640;
|
|
152
|
+
color: #f8fafc;
|
|
153
|
+
letter-spacing: 0.01em;
|
|
154
|
+
word-break: break-word;
|
|
155
|
+
}
|
|
156
|
+
.vista-error-meta {
|
|
157
|
+
margin: 0;
|
|
158
|
+
font-size: 12px;
|
|
159
|
+
color: rgba(226, 232, 240, 0.72);
|
|
160
|
+
}
|
|
161
|
+
.vista-error-controls {
|
|
162
|
+
display: flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
gap: 8px;
|
|
165
|
+
}
|
|
166
|
+
.vista-error-btn {
|
|
167
|
+
width: 30px;
|
|
168
|
+
height: 30px;
|
|
169
|
+
padding: 0;
|
|
170
|
+
border-radius: 9px;
|
|
171
|
+
border: 1px solid rgba(255, 255, 255, 0.22);
|
|
172
|
+
background: rgba(255, 255, 255, 0.04);
|
|
173
|
+
color: #e2e8f0;
|
|
174
|
+
display: inline-flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
justify-content: center;
|
|
177
|
+
cursor: pointer;
|
|
178
|
+
transition: all 120ms ease;
|
|
179
|
+
}
|
|
180
|
+
.vista-error-btn:hover {
|
|
181
|
+
background: rgba(255, 255, 255, 0.12);
|
|
182
|
+
border-color: rgba(255, 255, 255, 0.38);
|
|
183
|
+
}
|
|
184
|
+
.vista-error-btn svg {
|
|
185
|
+
width: 14px;
|
|
186
|
+
height: 14px;
|
|
187
|
+
display: block;
|
|
188
|
+
}
|
|
189
|
+
.vista-error-btn:focus-visible,
|
|
190
|
+
.vista-error-page-btn:focus-visible,
|
|
191
|
+
.vista-error-location:focus-visible {
|
|
192
|
+
outline: 2px solid rgba(255, 255, 255, 0.7);
|
|
193
|
+
outline-offset: 2px;
|
|
194
|
+
}
|
|
195
|
+
.vista-error-body {
|
|
196
|
+
padding: 16px 17px 17px;
|
|
197
|
+
overflow: auto;
|
|
198
|
+
display: grid;
|
|
199
|
+
grid-template-columns: 1fr;
|
|
200
|
+
gap: 11px;
|
|
201
|
+
}
|
|
202
|
+
.vista-error-card {
|
|
203
|
+
border: 1px solid rgba(255, 255, 255, 0.11);
|
|
204
|
+
border-radius: 11px;
|
|
205
|
+
background: rgba(255, 255, 255, 0.03);
|
|
206
|
+
padding: 12px;
|
|
207
|
+
}
|
|
208
|
+
.vista-error-card-title {
|
|
209
|
+
margin: 0 0 8px;
|
|
210
|
+
font-size: 11px;
|
|
211
|
+
letter-spacing: 0.08em;
|
|
212
|
+
text-transform: uppercase;
|
|
213
|
+
font-weight: 700;
|
|
214
|
+
color: rgba(226, 232, 240, 0.76);
|
|
215
|
+
}
|
|
216
|
+
.vista-error-pre {
|
|
217
|
+
margin: 0;
|
|
218
|
+
white-space: pre-wrap;
|
|
219
|
+
word-break: break-word;
|
|
220
|
+
font-size: 12.5px;
|
|
221
|
+
line-height: 1.58;
|
|
222
|
+
color: #f1f5f9;
|
|
223
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
224
|
+
}
|
|
225
|
+
.vista-error-tok-error { color: #fca5a5; font-weight: 640; }
|
|
226
|
+
.vista-error-tok-path { color: #93c5fd; }
|
|
227
|
+
.vista-error-tok-string { color: #86efac; }
|
|
228
|
+
.vista-error-tok-stack { color: #cbd5e1; }
|
|
229
|
+
.vista-error-tok-line { color: #fbbf24; }
|
|
230
|
+
.vista-error-tok-caret { color: #f87171; font-weight: 700; }
|
|
231
|
+
.vista-error-location {
|
|
232
|
+
width: 100%;
|
|
233
|
+
display: inline-flex;
|
|
234
|
+
align-items: center;
|
|
235
|
+
justify-content: flex-start;
|
|
236
|
+
border: 1px solid rgba(255, 255, 255, 0.16);
|
|
237
|
+
background: rgba(255, 255, 255, 0.04);
|
|
238
|
+
color: #93c5fd;
|
|
239
|
+
border-radius: 8px;
|
|
240
|
+
padding: 8px 10px;
|
|
241
|
+
font-size: 12px;
|
|
242
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
243
|
+
cursor: pointer;
|
|
244
|
+
}
|
|
245
|
+
.vista-error-location:hover {
|
|
246
|
+
background: rgba(255, 255, 255, 0.1);
|
|
247
|
+
}
|
|
248
|
+
.vista-error-page-root[data-minimized='true'] .vista-error-backdrop,
|
|
249
|
+
.vista-error-page-root[data-minimized='true'] .vista-error-panel {
|
|
250
|
+
display: none;
|
|
251
|
+
}
|
|
252
|
+
.vista-error-minimized-trigger {
|
|
253
|
+
position: fixed;
|
|
254
|
+
left: 28px;
|
|
255
|
+
bottom: 22px;
|
|
256
|
+
z-index: 2147483647;
|
|
257
|
+
height: 40px;
|
|
258
|
+
border-radius: 999px;
|
|
259
|
+
border: 1px solid rgba(248, 113, 113, 0.9);
|
|
260
|
+
background: rgba(53, 11, 16, 0.95);
|
|
261
|
+
color: #fecaca;
|
|
262
|
+
box-shadow: 0 10px 24px rgba(248, 113, 113, 0.24);
|
|
263
|
+
display: inline-flex;
|
|
264
|
+
align-items: center;
|
|
265
|
+
gap: 6px;
|
|
266
|
+
padding: 0 10px;
|
|
267
|
+
cursor: pointer;
|
|
268
|
+
}
|
|
269
|
+
.vista-error-minimized-trigger[hidden] {
|
|
270
|
+
display: none;
|
|
271
|
+
}
|
|
272
|
+
.vista-error-minimized-logo {
|
|
273
|
+
width: 14px;
|
|
274
|
+
height: 14px;
|
|
275
|
+
display: block;
|
|
276
|
+
}
|
|
277
|
+
.vista-error-minimized-close {
|
|
278
|
+
font-size: 12px;
|
|
279
|
+
line-height: 1;
|
|
280
|
+
color: #fca5a5;
|
|
281
|
+
}
|
|
282
|
+
.vista-error-minimized-count {
|
|
283
|
+
font-size: 11px;
|
|
284
|
+
font-weight: 670;
|
|
285
|
+
font-variant-numeric: tabular-nums;
|
|
286
|
+
}
|
|
287
|
+
@keyframes vista-overlay-in {
|
|
288
|
+
from { opacity: 0; transform: translateY(6px) scale(0.99); }
|
|
289
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
290
|
+
}
|
|
291
|
+
@media (max-width: 860px) {
|
|
292
|
+
.vista-error-page-root { padding: 12px; }
|
|
293
|
+
.vista-error-header { flex-direction: column; }
|
|
294
|
+
.vista-error-controls { width: 100%; justify-content: flex-end; }
|
|
295
|
+
.vista-error-title { font-size: 16px; }
|
|
296
|
+
.vista-error-minimized-trigger { left: 16px; bottom: 14px; }
|
|
297
|
+
}
|
|
211
298
|
`;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
var
|
|
222
|
-
window.location.href = 'vscode://file/' + normalized + ':' +
|
|
223
|
-
}
|
|
299
|
+
const OVERLAY_SCRIPT = `
|
|
300
|
+
function vistaReload() {
|
|
301
|
+
window.location.reload();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function vistaOpenInEditor(file, line, column) {
|
|
305
|
+
if (!file) return;
|
|
306
|
+
var normalized = String(file).replace(/\\\\/g, '/');
|
|
307
|
+
var lineNum = Number(line || 1);
|
|
308
|
+
var colNum = Number(column || 1);
|
|
309
|
+
window.location.href = 'vscode://file/' + normalized + ':' + lineNum + ':' + colNum;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function vistaCopyText(value) {
|
|
313
|
+
var text = String(value || '');
|
|
314
|
+
if (!text) return;
|
|
315
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
316
|
+
navigator.clipboard.writeText(text).catch(function () {});
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
var textarea = document.createElement('textarea');
|
|
320
|
+
textarea.value = text;
|
|
321
|
+
textarea.style.position = 'fixed';
|
|
322
|
+
textarea.style.opacity = '0';
|
|
323
|
+
textarea.style.pointerEvents = 'none';
|
|
324
|
+
document.body.appendChild(textarea);
|
|
325
|
+
textarea.focus();
|
|
326
|
+
textarea.select();
|
|
327
|
+
try {
|
|
328
|
+
document.execCommand('copy');
|
|
329
|
+
} catch (e) {}
|
|
330
|
+
document.body.removeChild(textarea);
|
|
331
|
+
}
|
|
224
332
|
`;
|
|
225
333
|
// ============================================================================
|
|
226
334
|
// Helpers
|
|
@@ -233,19 +341,139 @@ function escapeHtml(text) {
|
|
|
233
341
|
.replace(/"/g, '"')
|
|
234
342
|
.replace(/'/g, ''');
|
|
235
343
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
344
|
+
function escapeForInlineScript(text) {
|
|
345
|
+
return text.replace(/<\/script/gi, '<\\/script');
|
|
346
|
+
}
|
|
347
|
+
function colorizeLineHtml(line) {
|
|
348
|
+
let escaped = escapeHtml(line);
|
|
349
|
+
if (/^\s*\^+/.test(line)) {
|
|
350
|
+
return `<span class="vista-error-tok-caret">${escaped}</span>`;
|
|
351
|
+
}
|
|
352
|
+
if (/^\s*at\s+/.test(line)) {
|
|
353
|
+
return `<span class="vista-error-tok-stack">${escaped}</span>`;
|
|
354
|
+
}
|
|
355
|
+
const numbered = escaped.match(/^(\s*\d+)(\s*\|)(.*)$/);
|
|
356
|
+
if (numbered) {
|
|
357
|
+
escaped = `<span class="vista-error-tok-line">${numbered[1]}</span>${numbered[2]}${numbered[3]}`;
|
|
358
|
+
}
|
|
359
|
+
escaped = escaped.replace(/((?:[A-Za-z]:)?[\\/\w.@%:-]+\.(?:tsx?|jsx?|mjs|cjs|css|json|mdx?)(?::\d+(?::\d+)?)?)/g, '<span class="vista-error-tok-path">$1</span>');
|
|
360
|
+
escaped = escaped.replace(/("[^&]+"|'[^&]+'|`[^`]+`)/g, '<span class="vista-error-tok-string">$1</span>');
|
|
361
|
+
escaped = escaped.replace(/(TypeError:|ReferenceError:|SyntaxError:|Error:|Cannot find module|Module not found|Build Error|Runtime Error|Hydration Error)/g, '<span class="vista-error-tok-error">$1</span>');
|
|
362
|
+
return escaped;
|
|
363
|
+
}
|
|
364
|
+
function colorizeBlockHtml(value) {
|
|
365
|
+
return String(value || '')
|
|
366
|
+
.split(/\r?\n/)
|
|
367
|
+
.map((line) => colorizeLineHtml(line))
|
|
368
|
+
.join('\n');
|
|
244
369
|
}
|
|
245
370
|
function parseStackTrace(stack) {
|
|
246
371
|
if (!stack)
|
|
247
372
|
return [];
|
|
248
|
-
return stack
|
|
373
|
+
return stack
|
|
374
|
+
.split('\n')
|
|
375
|
+
.map((line) => line.trimEnd())
|
|
376
|
+
.filter((line) => line.trim().length > 0);
|
|
377
|
+
}
|
|
378
|
+
function normalizeError(error) {
|
|
379
|
+
return {
|
|
380
|
+
type: error?.type === 'build' || error?.type === 'hydration' || error?.type === 'runtime'
|
|
381
|
+
? error.type
|
|
382
|
+
: 'runtime',
|
|
383
|
+
message: typeof error?.message === 'string' ? error.message : 'Unknown Error',
|
|
384
|
+
stack: typeof error?.stack === 'string' ? error.stack : undefined,
|
|
385
|
+
file: typeof error?.file === 'string' ? error.file : undefined,
|
|
386
|
+
line: typeof error?.line === 'number' ? error.line : undefined,
|
|
387
|
+
column: typeof error?.column === 'number' ? error.column : undefined,
|
|
388
|
+
codeFrame: typeof error?.codeFrame === 'string' ? error.codeFrame : undefined,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function normalizeErrors(errors) {
|
|
392
|
+
if (!Array.isArray(errors) || errors.length === 0) {
|
|
393
|
+
return [
|
|
394
|
+
{
|
|
395
|
+
type: 'runtime',
|
|
396
|
+
message: 'Unknown Error',
|
|
397
|
+
},
|
|
398
|
+
];
|
|
399
|
+
}
|
|
400
|
+
return errors.map((error) => normalizeError(error));
|
|
401
|
+
}
|
|
402
|
+
function getErrorTypeLabel(type) {
|
|
403
|
+
if (type === 'build')
|
|
404
|
+
return 'Build Error';
|
|
405
|
+
if (type === 'hydration')
|
|
406
|
+
return 'Hydration Error';
|
|
407
|
+
return 'Runtime Error';
|
|
408
|
+
}
|
|
409
|
+
function getErrorTitle(message, fallback) {
|
|
410
|
+
const lines = message
|
|
411
|
+
.split(/\r?\n/)
|
|
412
|
+
.map((line) => line.trim())
|
|
413
|
+
.filter(Boolean);
|
|
414
|
+
const title = lines[0] || fallback;
|
|
415
|
+
return title.length > 140 ? `${title.slice(0, 137)}...` : title;
|
|
416
|
+
}
|
|
417
|
+
function formatLocation(error) {
|
|
418
|
+
if (!error.file)
|
|
419
|
+
return '';
|
|
420
|
+
const normalized = error.file.replace(/\\/g, '/');
|
|
421
|
+
if (!error.line)
|
|
422
|
+
return normalized;
|
|
423
|
+
return `${normalized}:${error.line}${error.column ? `:${error.column}` : ''}`;
|
|
424
|
+
}
|
|
425
|
+
function serializeErrorForCopy(error) {
|
|
426
|
+
const label = getErrorTypeLabel(error.type);
|
|
427
|
+
const parts = [label, '', error.message || 'Unknown Error'];
|
|
428
|
+
if (error.file) {
|
|
429
|
+
parts.push('');
|
|
430
|
+
parts.push(`File: ${formatLocation(error)}`);
|
|
431
|
+
}
|
|
432
|
+
if (error.codeFrame) {
|
|
433
|
+
parts.push('');
|
|
434
|
+
parts.push('Code Frame:');
|
|
435
|
+
parts.push(error.codeFrame);
|
|
436
|
+
}
|
|
437
|
+
if (error.stack) {
|
|
438
|
+
parts.push('');
|
|
439
|
+
parts.push('Stack Trace:');
|
|
440
|
+
parts.push(error.stack);
|
|
441
|
+
}
|
|
442
|
+
return parts.join('\n');
|
|
443
|
+
}
|
|
444
|
+
function openInEditorFromBrowser(file, line, column) {
|
|
445
|
+
if (typeof window === 'undefined' || !file)
|
|
446
|
+
return;
|
|
447
|
+
const normalized = file.replace(/\\/g, '/');
|
|
448
|
+
const lineNum = line || 1;
|
|
449
|
+
const colNum = column || 1;
|
|
450
|
+
window.location.href = `vscode://file/${normalized}:${lineNum}:${colNum}`;
|
|
451
|
+
}
|
|
452
|
+
function copyTextInBrowser(value) {
|
|
453
|
+
if (typeof window === 'undefined')
|
|
454
|
+
return;
|
|
455
|
+
const text = String(value || '');
|
|
456
|
+
if (!text)
|
|
457
|
+
return;
|
|
458
|
+
if (navigator.clipboard?.writeText) {
|
|
459
|
+
navigator.clipboard.writeText(text).catch(() => { });
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const textarea = document.createElement('textarea');
|
|
463
|
+
textarea.value = text;
|
|
464
|
+
textarea.style.position = 'fixed';
|
|
465
|
+
textarea.style.opacity = '0';
|
|
466
|
+
textarea.style.pointerEvents = 'none';
|
|
467
|
+
document.body.appendChild(textarea);
|
|
468
|
+
textarea.focus();
|
|
469
|
+
textarea.select();
|
|
470
|
+
try {
|
|
471
|
+
document.execCommand('copy');
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
// no-op
|
|
475
|
+
}
|
|
476
|
+
document.body.removeChild(textarea);
|
|
249
477
|
}
|
|
250
478
|
// ============================================================================
|
|
251
479
|
// Full-page HTML renderer (used directly by engines)
|
|
@@ -255,146 +483,439 @@ function parseStackTrace(stack) {
|
|
|
255
483
|
* Engines should send this directly: `res.status(500).send(renderErrorHTML(...))`.
|
|
256
484
|
*/
|
|
257
485
|
function renderErrorHTML(errors) {
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const
|
|
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
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
486
|
+
const normalizedErrors = normalizeErrors(errors);
|
|
487
|
+
const firstError = normalizedErrors[0];
|
|
488
|
+
const firstLabel = getErrorTypeLabel(firstError.type);
|
|
489
|
+
const firstTitle = getErrorTitle(firstError.message || 'Unknown Error', firstLabel);
|
|
490
|
+
const firstLocation = formatLocation(firstError);
|
|
491
|
+
const firstStack = parseStackTrace(firstError.stack || '').join('\n');
|
|
492
|
+
const firstCode = firstError.codeFrame || '';
|
|
493
|
+
const firstMessageHtml = colorizeBlockHtml(firstError.message || 'Unknown Error');
|
|
494
|
+
const firstCodeHtml = colorizeBlockHtml(firstCode);
|
|
495
|
+
const firstStackHtml = colorizeBlockHtml(firstStack);
|
|
496
|
+
const serializedErrors = escapeForInlineScript(JSON.stringify(normalizedErrors));
|
|
497
|
+
return `<!DOCTYPE html>
|
|
498
|
+
<html lang="en">
|
|
499
|
+
<head>
|
|
500
|
+
<meta charset="utf-8" />
|
|
501
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
502
|
+
<title>Error - Vista</title>
|
|
503
|
+
<style>${OVERLAY_STYLES}</style>
|
|
504
|
+
<script>${OVERLAY_SCRIPT}</script>
|
|
505
|
+
<script>
|
|
506
|
+
// Vista live-reload: auto-refresh error overlay when files change.
|
|
507
|
+
(function() {
|
|
508
|
+
function connect() {
|
|
509
|
+
var es = new EventSource('${constants_1.SSE_ENDPOINT}');
|
|
510
|
+
es.onmessage = function(e) {
|
|
511
|
+
if (e.data && e.data !== 'connected') {
|
|
512
|
+
window.location.reload();
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
es.onerror = function() {
|
|
516
|
+
es.close();
|
|
517
|
+
setTimeout(connect, 1500);
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
connect();
|
|
521
|
+
})();
|
|
522
|
+
|
|
523
|
+
(function() {
|
|
524
|
+
var errors = ${serializedErrors};
|
|
525
|
+
if (!Array.isArray(errors) || errors.length === 0) {
|
|
526
|
+
errors = [{ type: 'runtime', message: 'Unknown Error' }];
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
var state = { index: 0, errors: errors };
|
|
530
|
+
var typeNode;
|
|
531
|
+
var titleNode;
|
|
532
|
+
var metaNode;
|
|
533
|
+
var messageNode;
|
|
534
|
+
var locationWrap;
|
|
535
|
+
var locationText;
|
|
536
|
+
var locationButton;
|
|
537
|
+
var codeWrap;
|
|
538
|
+
var codeNode;
|
|
539
|
+
var stackWrap;
|
|
540
|
+
var stackNode;
|
|
541
|
+
var paginationNode;
|
|
542
|
+
var countNode;
|
|
543
|
+
var prevButton;
|
|
544
|
+
var nextButton;
|
|
545
|
+
var copyButton;
|
|
546
|
+
var rootNode;
|
|
547
|
+
var panelNode;
|
|
548
|
+
var backdropNode;
|
|
549
|
+
var minimizedTrigger;
|
|
550
|
+
var minimizedCount;
|
|
551
|
+
|
|
552
|
+
function getLabel(type) {
|
|
553
|
+
if (type === 'build') return 'Build Error';
|
|
554
|
+
if (type === 'hydration') return 'Hydration Error';
|
|
555
|
+
return 'Runtime Error';
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function getTitle(message, fallback) {
|
|
559
|
+
var lines = String(message || '')
|
|
560
|
+
.split(/\\r?\\n/)
|
|
561
|
+
.map(function(line) { return line.trim(); })
|
|
562
|
+
.filter(function(line) { return line.length > 0; });
|
|
563
|
+
var title = lines.length ? lines[0] : fallback;
|
|
564
|
+
return title.length > 140 ? title.slice(0, 137) + '...' : title;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
function pad2(value) {
|
|
568
|
+
return value < 10 ? '0' + value : String(value);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function formatTimeNow() {
|
|
572
|
+
var now = new Date();
|
|
573
|
+
return pad2(now.getHours()) + ':' + pad2(now.getMinutes()) + ':' + pad2(now.getSeconds());
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function currentError() {
|
|
577
|
+
if (!state.errors || state.errors.length === 0) return null;
|
|
578
|
+
var idx = state.index;
|
|
579
|
+
if (idx < 0) idx = 0;
|
|
580
|
+
if (idx > state.errors.length - 1) idx = state.errors.length - 1;
|
|
581
|
+
return state.errors[idx];
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function formatLocation(error) {
|
|
585
|
+
if (!error || !error.file) return '';
|
|
586
|
+
var file = String(error.file).replace(/\\\\/g, '/');
|
|
587
|
+
var line = Number(error.line || 0);
|
|
588
|
+
var column = Number(error.column || 0);
|
|
589
|
+
if (!line) return file;
|
|
590
|
+
return file + ':' + line + (column ? ':' + column : '');
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
function escapeHtml(value) {
|
|
594
|
+
return String(value || '')
|
|
595
|
+
.replace(/&/g, '&')
|
|
596
|
+
.replace(/</g, '<')
|
|
597
|
+
.replace(/>/g, '>')
|
|
598
|
+
.replace(/\"/g, '"')
|
|
599
|
+
.replace(/'/g, ''');
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function colorizeLine(line) {
|
|
603
|
+
var escaped = escapeHtml(line);
|
|
604
|
+
|
|
605
|
+
if (/^\\s*\\^+/.test(line)) {
|
|
606
|
+
return '<span class=\"vista-error-tok-caret\">' + escaped + '</span>';
|
|
607
|
+
}
|
|
608
|
+
if (/^\\s*at\\s+/.test(line)) {
|
|
609
|
+
return '<span class=\"vista-error-tok-stack\">' + escaped + '</span>';
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
var numbered = escaped.match(/^(\\s*\\d+)(\\s*\\|)(.*)$/);
|
|
613
|
+
if (numbered) {
|
|
614
|
+
escaped =
|
|
615
|
+
'<span class=\"vista-error-tok-line\">' + numbered[1] + '</span>' + numbered[2] + numbered[3];
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
escaped = escaped.replace(
|
|
619
|
+
/((?:[A-Za-z]:)?[\\\\/\\w.@%:-]+\\.(?:tsx?|jsx?|mjs|cjs|css|json|mdx?)(?::\\d+(?::\\d+)?)?)/g,
|
|
620
|
+
'<span class=\"vista-error-tok-path\">$1</span>'
|
|
621
|
+
);
|
|
622
|
+
escaped = escaped.replace(
|
|
623
|
+
/("[^&]+"|'[^&]+')/g,
|
|
624
|
+
'<span class=\"vista-error-tok-string\">$1</span>'
|
|
625
|
+
);
|
|
626
|
+
escaped = escaped.replace(
|
|
627
|
+
/(TypeError:|ReferenceError:|SyntaxError:|Error:|Cannot find module|Module not found|Build Error|Runtime Error|Hydration Error)/g,
|
|
628
|
+
'<span class=\"vista-error-tok-error\">$1</span>'
|
|
629
|
+
);
|
|
630
|
+
return escaped;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function colorizeBlock(value) {
|
|
634
|
+
return String(value || '')
|
|
635
|
+
.split(/\\r?\\n/)
|
|
636
|
+
.map(function(line) {
|
|
637
|
+
return colorizeLine(line);
|
|
638
|
+
})
|
|
639
|
+
.join('\\n');
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function minimizeOverlay() {
|
|
643
|
+
if (!rootNode) return;
|
|
644
|
+
rootNode.setAttribute('data-minimized', 'true');
|
|
645
|
+
if (minimizedTrigger) minimizedTrigger.hidden = false;
|
|
646
|
+
var indicator = window.__VISTA_DEVTOOLS_INDICATOR__;
|
|
647
|
+
if (indicator && typeof indicator.setError === 'function') {
|
|
648
|
+
indicator.setError('runtime-error', state.errors.length);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function restoreOverlay() {
|
|
653
|
+
if (!rootNode) return;
|
|
654
|
+
rootNode.removeAttribute('data-minimized');
|
|
655
|
+
if (minimizedTrigger) minimizedTrigger.hidden = true;
|
|
656
|
+
var indicator = window.__VISTA_DEVTOOLS_INDICATOR__;
|
|
657
|
+
if (indicator && typeof indicator.clearError === 'function') {
|
|
658
|
+
indicator.clearError();
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
function render() {
|
|
663
|
+
var error = currentError();
|
|
664
|
+
if (!error) return;
|
|
665
|
+
|
|
666
|
+
var label = getLabel(error.type);
|
|
667
|
+
var message = typeof error.message === 'string' ? error.message : String(error.message || 'Unknown Error');
|
|
668
|
+
var title = getTitle(message, label);
|
|
669
|
+
var location = formatLocation(error);
|
|
670
|
+
var codeFrame = typeof error.codeFrame === 'string' ? error.codeFrame : '';
|
|
671
|
+
var stack = typeof error.stack === 'string' ? error.stack.trim() : '';
|
|
672
|
+
|
|
673
|
+
if (typeNode) typeNode.textContent = label;
|
|
674
|
+
if (titleNode) titleNode.textContent = title;
|
|
675
|
+
if (metaNode) {
|
|
676
|
+
metaNode.textContent =
|
|
677
|
+
'Vista Dev Overlay | ' + formatTimeNow() + ' | ' + (state.index + 1) + ' of ' + state.errors.length;
|
|
678
|
+
}
|
|
679
|
+
if (messageNode) messageNode.innerHTML = colorizeBlock(message);
|
|
680
|
+
|
|
681
|
+
if (locationWrap) locationWrap.hidden = location.length === 0;
|
|
682
|
+
if (locationText) locationText.textContent = location;
|
|
683
|
+
|
|
684
|
+
if (codeWrap) codeWrap.hidden = codeFrame.trim().length === 0;
|
|
685
|
+
if (codeNode) codeNode.innerHTML = colorizeBlock(codeFrame);
|
|
686
|
+
|
|
687
|
+
if (stackWrap) stackWrap.hidden = stack.length === 0;
|
|
688
|
+
if (stackNode) stackNode.innerHTML = colorizeBlock(stack);
|
|
689
|
+
|
|
690
|
+
if (paginationNode) paginationNode.hidden = state.errors.length <= 1;
|
|
691
|
+
if (countNode) countNode.textContent = (state.index + 1) + ' / ' + state.errors.length;
|
|
692
|
+
if (prevButton) prevButton.disabled = state.index <= 0;
|
|
693
|
+
if (nextButton) nextButton.disabled = state.index >= state.errors.length - 1;
|
|
694
|
+
if (minimizedCount) minimizedCount.textContent = String(state.errors.length);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
function changeIndex(offset) {
|
|
698
|
+
var next = state.index + offset;
|
|
699
|
+
if (next < 0 || next > state.errors.length - 1) return;
|
|
700
|
+
state.index = next;
|
|
701
|
+
render();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
function bind() {
|
|
705
|
+
rootNode = document.querySelector('[data-vista-error-root]');
|
|
706
|
+
panelNode = document.querySelector('[data-vista-error-panel]');
|
|
707
|
+
backdropNode = document.querySelector('[data-vista-error-backdrop]');
|
|
708
|
+
typeNode = document.querySelector('[data-vista-error-type]');
|
|
709
|
+
titleNode = document.querySelector('[data-vista-error-title]');
|
|
710
|
+
metaNode = document.querySelector('[data-vista-error-meta]');
|
|
711
|
+
messageNode = document.querySelector('[data-vista-error-message]');
|
|
712
|
+
locationWrap = document.querySelector('[data-vista-location-wrap]');
|
|
713
|
+
locationText = document.querySelector('[data-vista-location-text]');
|
|
714
|
+
locationButton = document.querySelector('[data-vista-location-trigger]');
|
|
715
|
+
codeWrap = document.querySelector('[data-vista-code-wrap]');
|
|
716
|
+
codeNode = document.querySelector('[data-vista-code]');
|
|
717
|
+
stackWrap = document.querySelector('[data-vista-stack-wrap]');
|
|
718
|
+
stackNode = document.querySelector('[data-vista-stack]');
|
|
719
|
+
paginationNode = document.querySelector('[data-vista-pagination]');
|
|
720
|
+
countNode = document.querySelector('[data-vista-count]');
|
|
721
|
+
prevButton = document.querySelector('[data-vista-prev-btn]');
|
|
722
|
+
nextButton = document.querySelector('[data-vista-next-btn]');
|
|
723
|
+
copyButton = document.querySelector('[data-vista-copy-btn]');
|
|
724
|
+
minimizedTrigger = document.querySelector('[data-vista-minimized-trigger]');
|
|
725
|
+
minimizedCount = document.querySelector('[data-vista-minimized-count]');
|
|
726
|
+
|
|
727
|
+
if (prevButton) {
|
|
728
|
+
prevButton.addEventListener('click', function() { changeIndex(-1); });
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
if (nextButton) {
|
|
732
|
+
nextButton.addEventListener('click', function() { changeIndex(1); });
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
if (copyButton) {
|
|
736
|
+
copyButton.addEventListener('click', function() {
|
|
737
|
+
var error = currentError();
|
|
738
|
+
if (!error) return;
|
|
739
|
+
var label = getLabel(error.type);
|
|
740
|
+
var message = typeof error.message === 'string' ? error.message : String(error.message || 'Unknown Error');
|
|
741
|
+
var text = label + '\\n\\n' + message;
|
|
742
|
+
var location = formatLocation(error);
|
|
743
|
+
if (location) text += '\\n\\nFile: ' + location;
|
|
744
|
+
if (error.codeFrame) text += '\\n\\nCode Frame:\\n' + error.codeFrame;
|
|
745
|
+
if (error.stack) text += '\\n\\nStack Trace:\\n' + error.stack;
|
|
746
|
+
vistaCopyText(text);
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
if (locationButton) {
|
|
751
|
+
locationButton.addEventListener('click', function() {
|
|
752
|
+
var error = currentError();
|
|
753
|
+
if (!error || !error.file) return;
|
|
754
|
+
vistaOpenInEditor(error.file, Number(error.line || 1), Number(error.column || 1));
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
if (backdropNode) {
|
|
759
|
+
backdropNode.addEventListener('click', function() {
|
|
760
|
+
minimizeOverlay();
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
if (panelNode) {
|
|
765
|
+
panelNode.addEventListener('click', function(event) {
|
|
766
|
+
event.stopPropagation();
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (minimizedTrigger) {
|
|
771
|
+
minimizedTrigger.addEventListener('click', function() {
|
|
772
|
+
restoreOverlay();
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
document.addEventListener('keydown', function(event) {
|
|
777
|
+
if (event.key === 'ArrowLeft') {
|
|
778
|
+
changeIndex(-1);
|
|
779
|
+
} else if (event.key === 'ArrowRight') {
|
|
780
|
+
changeIndex(1);
|
|
781
|
+
} else if (event.key === 'Escape') {
|
|
782
|
+
minimizeOverlay();
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
788
|
+
bind();
|
|
789
|
+
render();
|
|
790
|
+
});
|
|
791
|
+
})();
|
|
792
|
+
</script>
|
|
793
|
+
</head>
|
|
794
|
+
<body>
|
|
795
|
+
<div class="vista-error-page-root" data-vista-error-root>
|
|
796
|
+
<div class="vista-error-backdrop" data-vista-error-backdrop></div>
|
|
797
|
+
<section class="vista-error-panel" data-vista-error-panel role="dialog" aria-label="Vista Error Overlay" aria-modal="true">
|
|
798
|
+
<header class="vista-error-header">
|
|
799
|
+
<div class="vista-error-head-left">
|
|
800
|
+
<div class="vista-error-top-row">
|
|
801
|
+
<span class="vista-error-badge" data-vista-error-type>
|
|
802
|
+
<span class="vista-error-badge-dot"></span>${escapeHtml(firstLabel)}
|
|
803
|
+
</span>
|
|
804
|
+
<div class="vista-error-pagination" data-vista-pagination${normalizedErrors.length <= 1 ? ' hidden' : ''}>
|
|
805
|
+
<button type="button" class="vista-error-page-btn" data-vista-prev-btn aria-label="Previous error"><</button>
|
|
806
|
+
<span class="vista-error-page-count" data-vista-count>1 / ${normalizedErrors.length}</span>
|
|
807
|
+
<button type="button" class="vista-error-page-btn" data-vista-next-btn aria-label="Next error">></button>
|
|
808
|
+
</div>
|
|
809
|
+
</div>
|
|
810
|
+
<h2 class="vista-error-title" data-vista-error-title>${escapeHtml(firstTitle)}</h2>
|
|
811
|
+
<p class="vista-error-meta" data-vista-error-meta>Vista Dev Overlay</p>
|
|
812
|
+
</div>
|
|
813
|
+
<div class="vista-error-controls">
|
|
814
|
+
<button type="button" class="vista-error-btn" data-vista-copy-btn aria-label="Copy error">
|
|
815
|
+
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><rect x="9" y="9" width="10" height="10" rx="2" stroke="currentColor" stroke-width="2"/><rect x="5" y="5" width="10" height="10" rx="2" stroke="currentColor" stroke-width="2"/></svg>
|
|
816
|
+
</button>
|
|
817
|
+
<button type="button" class="vista-error-btn" onclick="vistaReload()" aria-label="Reload page">
|
|
818
|
+
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M20 12a8 8 0 1 1-2.34-5.66" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><path d="M20 4V10H14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
819
|
+
</button>
|
|
820
|
+
</div>
|
|
821
|
+
</header>
|
|
822
|
+
|
|
823
|
+
<div class="vista-error-body">
|
|
824
|
+
<section class="vista-error-card" data-vista-location-wrap${firstLocation ? '' : ' hidden'}>
|
|
825
|
+
<h3 class="vista-error-card-title">Location</h3>
|
|
826
|
+
<button type="button" class="vista-error-location" data-vista-location-trigger>
|
|
827
|
+
<span data-vista-location-text>${escapeHtml(firstLocation)}</span>
|
|
828
|
+
</button>
|
|
829
|
+
</section>
|
|
830
|
+
|
|
831
|
+
<section class="vista-error-card">
|
|
832
|
+
<h3 class="vista-error-card-title">Message</h3>
|
|
833
|
+
<pre class="vista-error-pre" data-vista-error-message>${firstMessageHtml}</pre>
|
|
834
|
+
</section>
|
|
835
|
+
|
|
836
|
+
<section class="vista-error-card" data-vista-code-wrap${firstCode ? '' : ' hidden'}>
|
|
837
|
+
<h3 class="vista-error-card-title">Code Frame</h3>
|
|
838
|
+
<pre class="vista-error-pre" data-vista-code>${firstCodeHtml}</pre>
|
|
839
|
+
</section>
|
|
840
|
+
|
|
841
|
+
<section class="vista-error-card" data-vista-stack-wrap${firstStack ? '' : ' hidden'}>
|
|
842
|
+
<h3 class="vista-error-card-title">Stack Trace</h3>
|
|
843
|
+
<pre class="vista-error-pre" data-vista-stack>${firstStackHtml}</pre>
|
|
844
|
+
</section>
|
|
845
|
+
</div>
|
|
846
|
+
</section>
|
|
847
|
+
<button type="button" class="vista-error-minimized-trigger" data-vista-minimized-trigger hidden aria-label="Reopen error overlay">
|
|
848
|
+
<svg class="vista-error-minimized-logo" viewBox="0 0 168 177" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M81.872 176.988L-2.01405e-06 -2.68173e-06H30.5816L83.5576 121.604L136.774 -2.68173e-06H167.115L85.484 176.988H81.872Z" fill="white"/></svg>
|
|
849
|
+
<span class="vista-error-minimized-close">×</span>
|
|
850
|
+
<span class="vista-error-minimized-count" data-vista-minimized-count>${normalizedErrors.length}</span>
|
|
851
|
+
</button>
|
|
852
|
+
</div>
|
|
853
|
+
</body>
|
|
340
854
|
</html>`;
|
|
341
855
|
}
|
|
342
856
|
// ============================================================================
|
|
343
857
|
// React Component (kept for DevErrorBoundary + backwards compat)
|
|
344
858
|
// ============================================================================
|
|
345
859
|
function ErrorOverlay({ errors }) {
|
|
346
|
-
const
|
|
347
|
-
|
|
860
|
+
const normalizedErrors = react_1.default.useMemo(() => normalizeErrors(errors), [errors]);
|
|
861
|
+
const [activeIndex, setActiveIndex] = react_1.default.useState(0);
|
|
862
|
+
const [isMinimized, setIsMinimized] = react_1.default.useState(false);
|
|
863
|
+
react_1.default.useEffect(() => {
|
|
864
|
+
if (activeIndex > normalizedErrors.length - 1) {
|
|
865
|
+
setActiveIndex(0);
|
|
866
|
+
}
|
|
867
|
+
}, [activeIndex, normalizedErrors.length]);
|
|
868
|
+
const currentIndex = Math.max(0, Math.min(activeIndex, normalizedErrors.length - 1));
|
|
869
|
+
const error = normalizedErrors[currentIndex];
|
|
870
|
+
if (!error) {
|
|
348
871
|
return (0, jsx_runtime_1.jsx)("div", {});
|
|
349
|
-
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
</div>`,
|
|
397
|
-
} }));
|
|
872
|
+
}
|
|
873
|
+
const label = getErrorTypeLabel(error.type);
|
|
874
|
+
const title = getErrorTitle(error.message || 'Unknown Error', label);
|
|
875
|
+
const location = formatLocation(error);
|
|
876
|
+
const stackText = parseStackTrace(error.stack || '').join('\n');
|
|
877
|
+
const codeFrame = error.codeFrame || '';
|
|
878
|
+
const messageHtml = colorizeBlockHtml(error.message || 'Unknown Error');
|
|
879
|
+
const codeHtml = colorizeBlockHtml(codeFrame);
|
|
880
|
+
const stackHtml = colorizeBlockHtml(stackText);
|
|
881
|
+
const minimizeOverlay = react_1.default.useCallback(() => {
|
|
882
|
+
setIsMinimized(true);
|
|
883
|
+
if (typeof window !== 'undefined') {
|
|
884
|
+
const indicator = window.__VISTA_DEVTOOLS_INDICATOR__;
|
|
885
|
+
if (indicator && typeof indicator.setError === 'function') {
|
|
886
|
+
indicator.setError(title || 'Error', normalizedErrors.length);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}, [normalizedErrors.length, title]);
|
|
890
|
+
const restoreOverlay = react_1.default.useCallback(() => {
|
|
891
|
+
setIsMinimized(false);
|
|
892
|
+
if (typeof window !== 'undefined') {
|
|
893
|
+
const indicator = window.__VISTA_DEVTOOLS_INDICATOR__;
|
|
894
|
+
if (indicator && typeof indicator.clearError === 'function') {
|
|
895
|
+
indicator.clearError();
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}, []);
|
|
899
|
+
react_1.default.useEffect(() => {
|
|
900
|
+
const onKeyDown = (event) => {
|
|
901
|
+
if (event.key === 'Escape') {
|
|
902
|
+
minimizeOverlay();
|
|
903
|
+
}
|
|
904
|
+
else if (event.key === 'ArrowLeft') {
|
|
905
|
+
setActiveIndex((idx) => Math.max(0, idx - 1));
|
|
906
|
+
}
|
|
907
|
+
else if (event.key === 'ArrowRight') {
|
|
908
|
+
setActiveIndex((idx) => Math.min(normalizedErrors.length - 1, idx + 1));
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
window.addEventListener('keydown', onKeyDown);
|
|
912
|
+
return () => window.removeEventListener('keydown', onKeyDown);
|
|
913
|
+
}, [minimizeOverlay, normalizedErrors.length]);
|
|
914
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "vista-error-page-root", "data-embedded": "true", "data-minimized": isMinimized ? 'true' : undefined, children: [(0, jsx_runtime_1.jsx)("style", { children: OVERLAY_STYLES }), (0, jsx_runtime_1.jsx)("div", { className: "vista-error-backdrop", onClick: minimizeOverlay }), (0, jsx_runtime_1.jsxs)("section", { className: "vista-error-panel", role: "dialog", "aria-label": "Vista Error Overlay", "aria-modal": true, onClick: (event) => event.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("header", { className: "vista-error-header", children: [(0, jsx_runtime_1.jsxs)("div", { className: "vista-error-head-left", children: [(0, jsx_runtime_1.jsxs)("div", { className: "vista-error-top-row", children: [(0, jsx_runtime_1.jsxs)("span", { className: "vista-error-badge", children: [(0, jsx_runtime_1.jsx)("span", { className: "vista-error-badge-dot" }), label] }), normalizedErrors.length > 1 ? ((0, jsx_runtime_1.jsxs)("div", { className: "vista-error-pagination", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: "vista-error-page-btn", onClick: () => setActiveIndex((idx) => Math.max(0, idx - 1)), disabled: currentIndex === 0, "aria-label": "Previous error", children: '<' }), (0, jsx_runtime_1.jsxs)("span", { className: "vista-error-page-count", children: [currentIndex + 1, " / ", normalizedErrors.length] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "vista-error-page-btn", onClick: () => setActiveIndex((idx) => Math.min(normalizedErrors.length - 1, idx + 1)), disabled: currentIndex >= normalizedErrors.length - 1, "aria-label": "Next error", children: '>' })] })) : null] }), (0, jsx_runtime_1.jsx)("h2", { className: "vista-error-title", children: title }), (0, jsx_runtime_1.jsx)("p", { className: "vista-error-meta", children: "Vista Dev Overlay" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "vista-error-controls", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: "vista-error-btn", onClick: () => copyTextInBrowser(serializeErrorForCopy(error)), "aria-label": "Copy error", children: (0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("rect", { x: "9", y: "9", width: "10", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "2" }), (0, jsx_runtime_1.jsx)("rect", { x: "5", y: "5", width: "10", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "2" })] }) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "vista-error-btn", onClick: () => {
|
|
915
|
+
if (typeof window !== 'undefined') {
|
|
916
|
+
window.location.reload();
|
|
917
|
+
}
|
|
918
|
+
}, "aria-label": "Reload page", children: (0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M20 12a8 8 0 1 1-2.34-5.66", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }), (0, jsx_runtime_1.jsx)("path", { d: "M20 4V10H14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "vista-error-body", children: [location ? ((0, jsx_runtime_1.jsxs)("section", { className: "vista-error-card", children: [(0, jsx_runtime_1.jsx)("h3", { className: "vista-error-card-title", children: "Location" }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "vista-error-location", onClick: () => openInEditorFromBrowser(error.file, error.line, error.column), children: location })] })) : null, (0, jsx_runtime_1.jsxs)("section", { className: "vista-error-card", children: [(0, jsx_runtime_1.jsx)("h3", { className: "vista-error-card-title", children: "Message" }), (0, jsx_runtime_1.jsx)("pre", { className: "vista-error-pre", dangerouslySetInnerHTML: { __html: messageHtml } })] }), codeFrame ? ((0, jsx_runtime_1.jsxs)("section", { className: "vista-error-card", children: [(0, jsx_runtime_1.jsx)("h3", { className: "vista-error-card-title", children: "Code Frame" }), (0, jsx_runtime_1.jsx)("pre", { className: "vista-error-pre", dangerouslySetInnerHTML: { __html: codeHtml } })] })) : null, stackText ? ((0, jsx_runtime_1.jsxs)("section", { className: "vista-error-card", children: [(0, jsx_runtime_1.jsx)("h3", { className: "vista-error-card-title", children: "Stack Trace" }), (0, jsx_runtime_1.jsx)("pre", { className: "vista-error-pre", dangerouslySetInnerHTML: { __html: stackHtml } })] })) : null] })] }), isMinimized ? ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "vista-error-minimized-trigger", onClick: restoreOverlay, "aria-label": "Reopen error overlay", children: [(0, jsx_runtime_1.jsx)("svg", { className: "vista-error-minimized-logo", viewBox: "0 0 168 177", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: (0, jsx_runtime_1.jsx)("path", { d: "M81.872 176.988L-2.01405e-06 -2.68173e-06H30.5816L83.5576 121.604L136.774 -2.68173e-06H167.115L85.484 176.988H81.872Z", fill: "white" }) }), (0, jsx_runtime_1.jsx)("span", { className: "vista-error-minimized-close", children: "\u00D7" }), (0, jsx_runtime_1.jsx)("span", { className: "vista-error-minimized-count", children: normalizedErrors.length })] })) : null] }));
|
|
398
919
|
}
|
|
399
920
|
// ============================================================================
|
|
400
921
|
// Error Boundary (client-side)
|