vatts 1.2.0-alpha.1 → 1.2.0-alpha.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/dist/adapters/express.js +5 -1
- package/dist/adapters/factory.js +58 -21
- package/dist/adapters/fastify.js +5 -1
- package/dist/adapters/native.js +5 -1
- package/dist/api/console.js +25 -17
- package/dist/api/framework.js +22 -15
- package/dist/api/http.js +7 -2
- package/dist/builder.js +19 -10
- package/dist/client/clientRouter.js +6 -2
- package/dist/client/rpc.js +7 -4
- package/dist/env/env.js +18 -11
- package/dist/global/global.d.ts +177 -122
- package/dist/helpers.js +108 -67
- package/dist/hotReload.d.ts +6 -0
- package/dist/hotReload.js +179 -31
- package/dist/index.js +159 -115
- package/dist/react/BuildingPage.d.ts +2 -1
- package/dist/react/BuildingPage.js +47 -4
- package/dist/react/DefaultNotFound.d.ts +2 -1
- package/dist/react/DefaultNotFound.js +92 -17
- package/dist/react/DevIndicator.js +66 -23
- package/dist/react/ErrorModal.js +91 -40
- package/dist/react/Link.d.ts +2 -2
- package/dist/react/Link.js +27 -5
- package/dist/react/client.js +16 -5
- package/dist/react/entry.client.js +70 -30
- package/dist/react/image/Image.js +8 -3
- package/dist/react/renderer-react.js +53 -25
- package/dist/renderer.d.ts +4 -0
- package/dist/renderer.js +13 -5
- package/dist/router.js +82 -63
- package/dist/rpc/annotations.js +7 -3
- package/dist/rpc/server.js +21 -15
- package/dist/rpc/types.js +4 -1
- package/dist/types/framework.js +2 -1
- package/dist/types.js +2 -1
- package/dist/vue/App.vue +34 -37
- package/dist/vue/BuildingPage.vue +118 -102
- package/dist/vue/ErrorModal.vue +19 -37
- package/dist/vue/Link.vue +8 -7
- package/dist/vue/client.js +16 -6
- package/dist/vue/entry.client.js +8 -3
- package/dist/vue/image/Image.vue +25 -19
- package/dist/vue/renderer.vue.js +80 -26
- package/package.json +25 -12
- package/dist/global/global.js +0 -17
package/dist/vue/App.vue
CHANGED
|
@@ -24,32 +24,31 @@
|
|
|
24
24
|
</div>
|
|
25
25
|
</template>
|
|
26
26
|
|
|
27
|
-
<script setup
|
|
27
|
+
<script setup>
|
|
28
28
|
import { ref, computed, onMounted, onUnmounted, shallowRef, watch, nextTick } from 'vue';
|
|
29
|
-
import { router } from '../client/clientRouter';
|
|
30
|
-
import DevIndicator from './DevIndicator.vue';
|
|
31
|
-
import ErrorModal from './ErrorModal.vue';
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
layoutComponent?: any;
|
|
42
|
-
}>();
|
|
29
|
+
import { router } from '../client/clientRouter';
|
|
30
|
+
import DevIndicator from './DevIndicator.vue';
|
|
31
|
+
import ErrorModal from './ErrorModal.vue';
|
|
32
|
+
|
|
33
|
+
// --- Props ---
|
|
34
|
+
const props = defineProps({
|
|
35
|
+
componentMap: Object,
|
|
36
|
+
routes: Array,
|
|
37
|
+
initialComponentPath: String,
|
|
38
|
+
initialParams: null, // Aceita qualquer tipo
|
|
39
|
+
layoutComponent: null // Aceita componente ou null
|
|
40
|
+
});
|
|
43
41
|
|
|
44
42
|
// --- Estado ---
|
|
45
43
|
const hmrTimestamp = ref(Date.now());
|
|
46
|
-
|
|
47
|
-
const
|
|
44
|
+
// Removemos as tipagens e asserções "as any" diretas onde não são necessárias em JS
|
|
45
|
+
const buildError = ref(window.__VATTS_BUILD_ERROR__ || null);
|
|
46
|
+
const isErrorOpen = ref(!!window.__VATTS_BUILD_ERROR__);
|
|
48
47
|
const isDev = process.env.NODE_ENV !== 'production';
|
|
49
48
|
|
|
50
49
|
// --- HMR & Error Handling ---
|
|
51
|
-
const handleBuildError = (ev
|
|
52
|
-
const e = ev?.detail
|
|
50
|
+
const handleBuildError = (ev) => {
|
|
51
|
+
const e = ev?.detail;
|
|
53
52
|
buildError.value = e || null;
|
|
54
53
|
isErrorOpen.value = true;
|
|
55
54
|
};
|
|
@@ -70,7 +69,7 @@ const copyBuildError = async () => {
|
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
// --- Roteamento ---
|
|
73
|
-
const findRouteForPath = (path
|
|
72
|
+
const findRouteForPath = (path) => {
|
|
74
73
|
for (const route of props.routes) {
|
|
75
74
|
const regexPattern = route.pattern
|
|
76
75
|
.replace(/\[\[\.\.\.(\w+)\]\]/g, '(?<$1>.+)?')
|
|
@@ -92,9 +91,8 @@ const findRouteForPath = (path: string) => {
|
|
|
92
91
|
};
|
|
93
92
|
|
|
94
93
|
// Estado da Rota
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const params = ref<any>({});
|
|
94
|
+
const CurrentPageComponent = shallowRef(null);
|
|
95
|
+
const params = ref({});
|
|
98
96
|
|
|
99
97
|
const updateRoute = () => {
|
|
100
98
|
const currentPath = window.location.pathname.replace("index.html", '');
|
|
@@ -116,17 +114,16 @@ const updateRoute = () => {
|
|
|
116
114
|
// --- Computed para resolver o conteúdo final (404 vs Página) ---
|
|
117
115
|
const resolvedContent = computed(() => {
|
|
118
116
|
if (!CurrentPageComponent.value || props.initialComponentPath === '__404__') {
|
|
119
|
-
const NotFoundComponent =
|
|
117
|
+
const NotFoundComponent = window.__VATTS_NOT_FOUND__;
|
|
120
118
|
if (NotFoundComponent) return NotFoundComponent;
|
|
121
119
|
|
|
122
|
-
const DefaultNotFound =
|
|
120
|
+
const DefaultNotFound = window.__VATTS_DEFAULT_NOT_FOUND__;
|
|
123
121
|
return DefaultNotFound || 'div'; // Fallback seguro
|
|
124
122
|
}
|
|
125
123
|
return CurrentPageComponent.value;
|
|
126
124
|
});
|
|
127
125
|
|
|
128
126
|
const contentProps = computed(() => {
|
|
129
|
-
// Se for 404, talvez não queira passar params, mas mantendo a lógica original:
|
|
130
127
|
if (!CurrentPageComponent.value) return {};
|
|
131
128
|
return { params: params.value };
|
|
132
129
|
});
|
|
@@ -141,42 +138,42 @@ onMounted(() => {
|
|
|
141
138
|
updateRoute();
|
|
142
139
|
|
|
143
140
|
// Listeners de Build
|
|
144
|
-
window.addEventListener('vatts:build-error'
|
|
145
|
-
window.addEventListener('vatts:build-ok'
|
|
141
|
+
window.addEventListener('vatts:build-error', handleBuildError);
|
|
142
|
+
window.addEventListener('vatts:build-ok', handleBuildOk);
|
|
146
143
|
|
|
147
144
|
// Listeners de Rota
|
|
148
145
|
window.addEventListener('popstate', updateRoute);
|
|
149
146
|
const unsubscribeRouter = router.subscribe(updateRoute);
|
|
150
147
|
|
|
151
148
|
// HMR Listener
|
|
152
|
-
|
|
153
|
-
const handleHMRUpdate = (event
|
|
149
|
+
window.__HWEB_HMR__ = true;
|
|
150
|
+
const handleHMRUpdate = (event) => {
|
|
154
151
|
const { file, timestamp } = event.detail;
|
|
155
152
|
const fileName = file ? file.split('/').pop()?.split('\\').pop() : 'unknown';
|
|
156
153
|
console.log('🔥 HMR: Component Update Triggered', fileName);
|
|
157
154
|
|
|
158
155
|
try {
|
|
159
156
|
hmrTimestamp.value = timestamp;
|
|
160
|
-
|
|
157
|
+
window.__HMR_SUCCESS__ = true;
|
|
161
158
|
setTimeout(() => {
|
|
162
|
-
|
|
159
|
+
window.__HMR_SUCCESS__ = false;
|
|
163
160
|
}, 3000);
|
|
164
161
|
|
|
165
162
|
// Força update da rota caso o componente tenha mudado
|
|
166
163
|
updateRoute();
|
|
167
164
|
} catch (error) {
|
|
168
165
|
console.error('❌ HMR Error:', error);
|
|
169
|
-
|
|
166
|
+
window.__HMR_SUCCESS__ = false;
|
|
170
167
|
}
|
|
171
168
|
};
|
|
172
|
-
window.addEventListener('hmr:component-update'
|
|
169
|
+
window.addEventListener('hmr:component-update', handleHMRUpdate);
|
|
173
170
|
|
|
174
171
|
// Cleanup
|
|
175
172
|
onUnmounted(() => {
|
|
176
|
-
window.removeEventListener('vatts:build-error'
|
|
177
|
-
window.removeEventListener('vatts:build-ok'
|
|
173
|
+
window.removeEventListener('vatts:build-error', handleBuildError);
|
|
174
|
+
window.removeEventListener('vatts:build-ok', handleBuildOk);
|
|
178
175
|
window.removeEventListener('popstate', updateRoute);
|
|
179
|
-
window.removeEventListener('hmr:component-update'
|
|
176
|
+
window.removeEventListener('hmr:component-update', handleHMRUpdate);
|
|
180
177
|
unsubscribeRouter();
|
|
181
178
|
});
|
|
182
179
|
});
|
|
@@ -1,68 +1,15 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
|
|
2
|
+
import { onMounted, ref } from 'vue';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const version = ref("1.0.0");
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// Se precisar importar o package.json, use: import pkg from '../package.json';
|
|
9
|
-
// version.value = require("../package.json").version;
|
|
6
|
+
try {
|
|
7
|
+
version.value = require("../../package.json").version;
|
|
10
8
|
} catch (e) {}
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}, 2500);
|
|
16
|
-
});
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<template>
|
|
20
|
-
<div class="building-screen-body">
|
|
21
|
-
<!-- Links de fonte inseridos aqui para manter a fidelidade ao original -->
|
|
22
|
-
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
23
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
24
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
25
|
-
|
|
26
|
-
<div class="container">
|
|
27
|
-
<div class="build-card">
|
|
28
|
-
<div class="neon-line"></div>
|
|
29
|
-
|
|
30
|
-
<div class="content">
|
|
31
|
-
<div class="logo-wrapper">
|
|
32
|
-
<div class="logo-glow"></div>
|
|
33
|
-
<img src="https://raw.githubusercontent.com/mfrazlab/vatts.js/master/docs/public/logo.png" alt="Vatts Logo" />
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<h1>Vatts<span>.js</span></h1>
|
|
37
|
-
<p>Building your masterpiece...</p>
|
|
38
|
-
|
|
39
|
-
<div class="terminal-box">
|
|
40
|
-
<div class="term-line">
|
|
41
|
-
<div class="term-spinner"></div>
|
|
42
|
-
<span class="file-name">Compiling <span class="accent">src/vatts.ts</span>...</span>
|
|
43
|
-
</div>
|
|
44
|
-
<div class="term-line" style="opacity: 0.5">
|
|
45
|
-
<span>✓</span>
|
|
46
|
-
<span class="file-name">Optimizing assets</span>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
<div class="card-footer">
|
|
52
|
-
<span>Building...</span>
|
|
53
|
-
<div class="status-active">
|
|
54
|
-
<div class="dot"></div>
|
|
55
|
-
v{{ version }}
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
</template>
|
|
62
|
-
|
|
63
|
-
<style scoped>
|
|
64
|
-
/* Variáveis definidas no escopo do componente */
|
|
65
|
-
.building-screen-body {
|
|
10
|
+
// CSS extraído para evitar que o Vue escape caracteres como '>' ou aspas
|
|
11
|
+
const cssStyles = `
|
|
12
|
+
:root {
|
|
66
13
|
--bg-solid: #000000;
|
|
67
14
|
--card-bg: #0a0a0a;
|
|
68
15
|
/* PALETA: Monocromática estilo Next.js */
|
|
@@ -70,7 +17,9 @@
|
|
|
70
17
|
--primary-glow: rgba(255, 255, 255, 0.1);
|
|
71
18
|
--text-main: #ffffff;
|
|
72
19
|
--text-muted: #64748b;
|
|
20
|
+
}
|
|
73
21
|
|
|
22
|
+
body {
|
|
74
23
|
margin: 0;
|
|
75
24
|
padding: 0;
|
|
76
25
|
width: 100vw;
|
|
@@ -80,9 +29,9 @@
|
|
|
80
29
|
color: var(--text-main);
|
|
81
30
|
overflow: hidden;
|
|
82
31
|
position: relative;
|
|
83
|
-
}
|
|
32
|
+
}
|
|
84
33
|
|
|
85
|
-
|
|
34
|
+
.container {
|
|
86
35
|
position: absolute;
|
|
87
36
|
top: 50%;
|
|
88
37
|
left: 50%;
|
|
@@ -92,9 +41,9 @@
|
|
|
92
41
|
align-items: center;
|
|
93
42
|
width: 100%;
|
|
94
43
|
pointer-events: none;
|
|
95
|
-
}
|
|
44
|
+
}
|
|
96
45
|
|
|
97
|
-
|
|
46
|
+
.build-card {
|
|
98
47
|
pointer-events: auto;
|
|
99
48
|
position: relative;
|
|
100
49
|
width: 100%;
|
|
@@ -108,31 +57,31 @@
|
|
|
108
57
|
flex-direction: column;
|
|
109
58
|
align-items: center;
|
|
110
59
|
text-align: center;
|
|
111
|
-
}
|
|
60
|
+
}
|
|
112
61
|
|
|
113
|
-
|
|
62
|
+
.neon-line {
|
|
114
63
|
height: 1px;
|
|
115
64
|
width: 100%;
|
|
116
65
|
/* Linha de luz branca/cinza */
|
|
117
66
|
background: linear-gradient(90deg, transparent, #334155, #ffffff, #334155, transparent);
|
|
118
67
|
box-shadow: 0 0 15px rgba(255, 255, 255, 0.05);
|
|
119
|
-
}
|
|
68
|
+
}
|
|
120
69
|
|
|
121
|
-
|
|
70
|
+
.content {
|
|
122
71
|
padding: 40px 32px;
|
|
123
72
|
width: 100%;
|
|
124
73
|
box-sizing: border-box;
|
|
125
74
|
display: flex;
|
|
126
75
|
flex-direction: column;
|
|
127
76
|
align-items: center;
|
|
128
|
-
}
|
|
77
|
+
}
|
|
129
78
|
|
|
130
|
-
|
|
79
|
+
.logo-wrapper {
|
|
131
80
|
position: relative;
|
|
132
81
|
margin-bottom: 24px;
|
|
133
|
-
}
|
|
82
|
+
}
|
|
134
83
|
|
|
135
|
-
|
|
84
|
+
.logo-wrapper img {
|
|
136
85
|
width: 64px;
|
|
137
86
|
height: 64px;
|
|
138
87
|
object-fit: contain;
|
|
@@ -140,9 +89,9 @@
|
|
|
140
89
|
z-index: 2;
|
|
141
90
|
/* Deixa a logo levemente dessaturada para combinar */
|
|
142
91
|
filter: grayscale(0.5);
|
|
143
|
-
}
|
|
92
|
+
}
|
|
144
93
|
|
|
145
|
-
|
|
94
|
+
.logo-glow {
|
|
146
95
|
position: absolute;
|
|
147
96
|
top: 50%;
|
|
148
97
|
left: 50%;
|
|
@@ -154,9 +103,9 @@
|
|
|
154
103
|
opacity: 0.1;
|
|
155
104
|
border-radius: 50%;
|
|
156
105
|
animation: pulse 2s ease-in-out infinite;
|
|
157
|
-
}
|
|
106
|
+
}
|
|
158
107
|
|
|
159
|
-
|
|
108
|
+
h1 {
|
|
160
109
|
margin: 0;
|
|
161
110
|
font-size: 2rem;
|
|
162
111
|
font-weight: 800;
|
|
@@ -164,23 +113,21 @@
|
|
|
164
113
|
background: linear-gradient(180deg, #ffffff 0%, #475569 100%);
|
|
165
114
|
-webkit-background-clip: text;
|
|
166
115
|
-webkit-text-fill-color: transparent;
|
|
167
|
-
|
|
168
|
-
color: #ffffff;
|
|
169
|
-
}
|
|
116
|
+
}
|
|
170
117
|
|
|
171
|
-
|
|
118
|
+
h1 span {
|
|
172
119
|
color: #475569;
|
|
173
120
|
-webkit-text-fill-color: #475569;
|
|
174
|
-
}
|
|
121
|
+
}
|
|
175
122
|
|
|
176
|
-
|
|
123
|
+
p {
|
|
177
124
|
margin: 8px 0 32px 0;
|
|
178
125
|
color: var(--text-muted);
|
|
179
126
|
font-size: 0.9rem;
|
|
180
127
|
font-weight: 500;
|
|
181
|
-
}
|
|
128
|
+
}
|
|
182
129
|
|
|
183
|
-
|
|
130
|
+
.terminal-box {
|
|
184
131
|
width: 100%;
|
|
185
132
|
background: rgba(255, 255, 255, 0.02);
|
|
186
133
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
@@ -194,27 +141,27 @@
|
|
|
194
141
|
display: flex;
|
|
195
142
|
flex-direction: column;
|
|
196
143
|
gap: 8px;
|
|
197
|
-
}
|
|
144
|
+
}
|
|
198
145
|
|
|
199
|
-
|
|
146
|
+
.term-line {
|
|
200
147
|
display: flex;
|
|
201
148
|
align-items: center;
|
|
202
149
|
gap: 8px;
|
|
203
|
-
}
|
|
150
|
+
}
|
|
204
151
|
|
|
205
|
-
|
|
152
|
+
.term-spinner {
|
|
206
153
|
width: 10px;
|
|
207
154
|
height: 10px;
|
|
208
155
|
border: 2px solid rgba(255, 255, 255, 0.1);
|
|
209
156
|
border-top-color: #ffffff;
|
|
210
157
|
border-radius: 50%;
|
|
211
158
|
animation: spin 0.6s linear infinite;
|
|
212
|
-
}
|
|
159
|
+
}
|
|
213
160
|
|
|
214
|
-
|
|
215
|
-
|
|
161
|
+
.file-name { color: #94a3b8; }
|
|
162
|
+
.accent { color: #ffffff; }
|
|
216
163
|
|
|
217
|
-
|
|
164
|
+
.card-footer {
|
|
218
165
|
width: 100%;
|
|
219
166
|
padding: 12px 32px;
|
|
220
167
|
background: rgba(255,255,255,0.02);
|
|
@@ -225,9 +172,9 @@
|
|
|
225
172
|
font-size: 11px;
|
|
226
173
|
color: rgba(255,255,255,0.2);
|
|
227
174
|
box-sizing: border-box;
|
|
228
|
-
}
|
|
175
|
+
}
|
|
229
176
|
|
|
230
|
-
|
|
177
|
+
.status-active {
|
|
231
178
|
display: flex;
|
|
232
179
|
align-items: center;
|
|
233
180
|
gap: 6px;
|
|
@@ -235,22 +182,91 @@
|
|
|
235
182
|
font-weight: 600;
|
|
236
183
|
text-transform: uppercase;
|
|
237
184
|
letter-spacing: 0.05em;
|
|
238
|
-
}
|
|
185
|
+
}
|
|
239
186
|
|
|
240
|
-
|
|
187
|
+
.dot {
|
|
241
188
|
width: 6px;
|
|
242
189
|
height: 6px;
|
|
243
190
|
background-color: #ffffff;
|
|
244
191
|
border-radius: 50%;
|
|
245
192
|
box-shadow: 0 0 8px rgba(255, 255, 255, 0.5);
|
|
246
|
-
}
|
|
193
|
+
}
|
|
247
194
|
|
|
248
|
-
|
|
195
|
+
@keyframes pulse {
|
|
249
196
|
0%, 100% { opacity: 0.1; transform: translate(-50%, -50%) scale(1); }
|
|
250
197
|
50% { opacity: 0.15; transform: translate(-50%, -50%) scale(1.1); }
|
|
251
|
-
}
|
|
198
|
+
}
|
|
252
199
|
|
|
253
|
-
|
|
200
|
+
@keyframes spin {
|
|
254
201
|
to { transform: rotate(360deg); }
|
|
255
|
-
}
|
|
256
|
-
|
|
202
|
+
}
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
// Script de reload extraído
|
|
206
|
+
const clientReloadScript = `
|
|
207
|
+
setTimeout(() => {
|
|
208
|
+
window.location.reload();
|
|
209
|
+
}, 2500);
|
|
210
|
+
`;
|
|
211
|
+
</script>
|
|
212
|
+
|
|
213
|
+
<template>
|
|
214
|
+
<html>
|
|
215
|
+
<head>
|
|
216
|
+
<meta charset="UTF-8" />
|
|
217
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
218
|
+
<title>Vatts.js | Building...</title>
|
|
219
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
220
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
221
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
222
|
+
|
|
223
|
+
<!-- v-html garante que o CSS seja renderizado sem escape (ex: '>' permanece '>') -->
|
|
224
|
+
<style v-html="cssStyles"></style>
|
|
225
|
+
</head>
|
|
226
|
+
<body>
|
|
227
|
+
<div class="building-screen-body">
|
|
228
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
229
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
230
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
231
|
+
|
|
232
|
+
<div class="container">
|
|
233
|
+
<div class="build-card">
|
|
234
|
+
<div class="neon-line"></div>
|
|
235
|
+
|
|
236
|
+
<div class="content">
|
|
237
|
+
<div class="logo-wrapper">
|
|
238
|
+
<div class="logo-glow"></div>
|
|
239
|
+
<img src="https://raw.githubusercontent.com/mfrazlab/vatts.js/master/docs/public/logo.png" alt="Vatts Logo" />
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<h1>Vatts<span>.js</span></h1>
|
|
243
|
+
<p>Building your application...</p>
|
|
244
|
+
|
|
245
|
+
<div class="terminal-box">
|
|
246
|
+
<div class="term-line">
|
|
247
|
+
<div class="term-spinner"></div>
|
|
248
|
+
<span class="file-name">Compiling <span class="accent">src/vatts.ts</span>...</span>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="term-line" style="opacity: 0.5">
|
|
251
|
+
<span>✓</span>
|
|
252
|
+
<span class="file-name">Optimizing assets</span>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
|
|
257
|
+
<div class="card-footer">
|
|
258
|
+
<span>Building...</span>
|
|
259
|
+
<div class="status-active">
|
|
260
|
+
<div class="dot"></div>
|
|
261
|
+
v{{ version }}
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<!-- v-html para o script garante que a arrow function não quebre com '>' -->
|
|
269
|
+
<script v-html="clientReloadScript"></script>
|
|
270
|
+
</body>
|
|
271
|
+
</html>
|
|
272
|
+
</template>
|
package/dist/vue/ErrorModal.vue
CHANGED
|
@@ -58,34 +58,16 @@
|
|
|
58
58
|
</Teleport>
|
|
59
59
|
</template>
|
|
60
60
|
|
|
61
|
-
<script setup
|
|
61
|
+
<script setup>
|
|
62
62
|
import { ref, computed, watch, onMounted, onUnmounted, useAttrs } from 'vue';
|
|
63
63
|
|
|
64
|
-
// --- Interface Exportada para uso no App.vue ---
|
|
65
|
-
export interface VattsBuildError {
|
|
66
|
-
message?: string;
|
|
67
|
-
name?: string;
|
|
68
|
-
stack?: string;
|
|
69
|
-
frame?: string;
|
|
70
|
-
id?: string;
|
|
71
|
-
plugin?: string;
|
|
72
|
-
pluginCode?: string;
|
|
73
|
-
loc?: any;
|
|
74
|
-
watchFiles?: any;
|
|
75
|
-
cause?: any;
|
|
76
|
-
ts?: number;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
64
|
// --- Props e Emits ---
|
|
80
|
-
const props = defineProps
|
|
81
|
-
error:
|
|
82
|
-
isOpen:
|
|
83
|
-
}
|
|
65
|
+
const props = defineProps({
|
|
66
|
+
error: Object,
|
|
67
|
+
isOpen: Boolean
|
|
68
|
+
});
|
|
84
69
|
|
|
85
|
-
const emit = defineEmits
|
|
86
|
-
(e: 'close'): void;
|
|
87
|
-
(e: 'copy'): void;
|
|
88
|
-
}>();
|
|
70
|
+
const emit = defineEmits(['close', 'copy']);
|
|
89
71
|
|
|
90
72
|
// Verifica se o pai (App.vue) passou um listener para @copy
|
|
91
73
|
const attrs = useAttrs();
|
|
@@ -98,7 +80,7 @@ const isHoveringClose = ref(false);
|
|
|
98
80
|
const isHoveringCopy = ref(false);
|
|
99
81
|
|
|
100
82
|
// --- Lógica de Parser ANSI ---
|
|
101
|
-
const ANSI_COLORS
|
|
83
|
+
const ANSI_COLORS = {
|
|
102
84
|
'30': '#475569',
|
|
103
85
|
'31': '#ef4444',
|
|
104
86
|
'32': '#ffffff',
|
|
@@ -110,13 +92,13 @@ const ANSI_COLORS: Record<string, string> = {
|
|
|
110
92
|
'90': '#64748b',
|
|
111
93
|
};
|
|
112
94
|
|
|
113
|
-
function parseAnsi(text
|
|
95
|
+
function parseAnsi(text) {
|
|
114
96
|
if (!text) return [];
|
|
115
97
|
const regex = /\u001b\[(\d+)(?:;\d+)*m/g;
|
|
116
98
|
const result = [];
|
|
117
99
|
let lastIndex = 0;
|
|
118
100
|
let match;
|
|
119
|
-
let currentColor
|
|
101
|
+
let currentColor = null;
|
|
120
102
|
|
|
121
103
|
while ((match = regex.exec(text)) !== null) {
|
|
122
104
|
const rawText = text.slice(lastIndex, match.index);
|
|
@@ -164,7 +146,7 @@ watch(() => props.isOpen, (newVal) => {
|
|
|
164
146
|
}, { immediate: true });
|
|
165
147
|
|
|
166
148
|
// Listener para tecla ESC
|
|
167
|
-
const onKey = (e
|
|
149
|
+
const onKey = (e) => {
|
|
168
150
|
if (e.key === 'Escape' && props.isOpen) emit('close');
|
|
169
151
|
};
|
|
170
152
|
|
|
@@ -182,9 +164,9 @@ onUnmounted(() => {
|
|
|
182
164
|
const close = () => emit('close');
|
|
183
165
|
const copy = () => emit('copy');
|
|
184
166
|
|
|
185
|
-
// --- Estilos
|
|
167
|
+
// --- Estilos ---
|
|
186
168
|
const overlayStyle = computed(() => ({
|
|
187
|
-
position: 'fixed'
|
|
169
|
+
position: 'fixed',
|
|
188
170
|
top: 0,
|
|
189
171
|
left: 0,
|
|
190
172
|
width: '100vw',
|
|
@@ -199,7 +181,7 @@ const overlayStyle = computed(() => ({
|
|
|
199
181
|
padding: '24px',
|
|
200
182
|
transition: 'all 0.3s ease',
|
|
201
183
|
opacity: visible.value ? 1 : 0,
|
|
202
|
-
boxSizing: 'border-box'
|
|
184
|
+
boxSizing: 'border-box',
|
|
203
185
|
}));
|
|
204
186
|
|
|
205
187
|
const cardStyle = computed(() => ({
|
|
@@ -207,14 +189,14 @@ const cardStyle = computed(() => ({
|
|
|
207
189
|
maxWidth: '1080px',
|
|
208
190
|
maxHeight: '90vh',
|
|
209
191
|
display: 'flex',
|
|
210
|
-
flexDirection: 'column'
|
|
192
|
+
flexDirection: 'column',
|
|
211
193
|
background: '#0a0a0a',
|
|
212
194
|
boxShadow: `0 0 0 1px rgba(255, 255, 255, 0.1), 0 50px 100px -20px rgba(0, 0, 0, 1)`,
|
|
213
195
|
borderRadius: '16px',
|
|
214
196
|
overflow: 'hidden',
|
|
215
197
|
transform: visible.value ? 'scale(1) translateY(0)' : 'scale(0.98) translateY(10px)',
|
|
216
198
|
transition: 'transform 0.4s cubic-bezier(0.16, 1, 0.3, 1)',
|
|
217
|
-
position: 'relative'
|
|
199
|
+
position: 'relative',
|
|
218
200
|
}));
|
|
219
201
|
|
|
220
202
|
const neonLineStyle = {
|
|
@@ -261,8 +243,8 @@ const terminalContentStyle = {
|
|
|
261
243
|
fontSize: '13px',
|
|
262
244
|
lineHeight: 1.6,
|
|
263
245
|
color: '#e2e8f0',
|
|
264
|
-
whiteSpace: 'pre-wrap'
|
|
265
|
-
wordBreak: 'break-word'
|
|
246
|
+
whiteSpace: 'pre-wrap',
|
|
247
|
+
wordBreak: 'break-word',
|
|
266
248
|
};
|
|
267
249
|
|
|
268
250
|
const stackContainerStyle = {
|
|
@@ -283,7 +265,7 @@ const footerStyle = {
|
|
|
283
265
|
fontFamily: 'Inter, sans-serif'
|
|
284
266
|
};
|
|
285
267
|
|
|
286
|
-
const getBtnStyle = (kind
|
|
268
|
+
const getBtnStyle = (kind, hovering) => {
|
|
287
269
|
const base = {
|
|
288
270
|
padding: '8px 16px',
|
|
289
271
|
borderRadius: '8px',
|
|
@@ -291,7 +273,7 @@ const getBtnStyle = (kind: 'primary' | 'secondary', hovering: boolean) => {
|
|
|
291
273
|
fontWeight: 700,
|
|
292
274
|
cursor: 'pointer',
|
|
293
275
|
transition: 'all 0.2s ease',
|
|
294
|
-
textTransform: 'uppercase'
|
|
276
|
+
textTransform: 'uppercase',
|
|
295
277
|
letterSpacing: '0.05em',
|
|
296
278
|
border: 'none',
|
|
297
279
|
outline: 'none',
|
package/dist/vue/Link.vue
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
<script setup
|
|
1
|
+
<script setup>
|
|
2
2
|
import { router } from '../client/clientRouter';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
href:
|
|
6
|
-
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
href: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true
|
|
8
|
+
}
|
|
9
|
+
});
|
|
7
10
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const handleClick = async (e: MouseEvent) => {
|
|
11
|
+
const handleClick = async (e) => {
|
|
11
12
|
e.preventDefault();
|
|
12
13
|
|
|
13
14
|
// Usa o novo sistema de router
|
package/dist/vue/client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* This file is part of the Vatts.js Project.
|
|
3
4
|
* Copyright (c) 2026 itsmuzin
|
|
@@ -14,11 +15,20 @@
|
|
|
14
15
|
* See the License for the specific language governing permissions and
|
|
15
16
|
* limitations under the License.
|
|
16
17
|
*/
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.VattsImage = exports.Image = exports.importServer = exports.router = exports.Link = void 0;
|
|
17
23
|
// Este arquivo exporta apenas código seguro para o cliente (navegador)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
const Link_vue_1 = __importDefault(require("./Link.vue"));
|
|
25
|
+
exports.Link = Link_vue_1.default;
|
|
26
|
+
var clientRouter_1 = require("../client/clientRouter");
|
|
27
|
+
Object.defineProperty(exports, "router", { enumerable: true, get: function () { return clientRouter_1.router; } });
|
|
21
28
|
// RPC (client-side)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
var rpc_1 = require("../client/rpc");
|
|
30
|
+
Object.defineProperty(exports, "importServer", { enumerable: true, get: function () { return rpc_1.importServer; } });
|
|
31
|
+
var Image_vue_1 = require("./image/Image.vue");
|
|
32
|
+
Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return __importDefault(Image_vue_1).default; } });
|
|
33
|
+
var Image_vue_2 = require("./image/Image.vue");
|
|
34
|
+
Object.defineProperty(exports, "VattsImage", { enumerable: true, get: function () { return __importDefault(Image_vue_2).default; } });
|