vatts 1.1.4-alpha.9 → 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.
Files changed (59) hide show
  1. package/dist/adapters/express.js +2 -3
  2. package/dist/adapters/factory.js +1 -1
  3. package/dist/adapters/fastify.js +2 -3
  4. package/dist/adapters/native.js +6 -7
  5. package/dist/api/console.js +11 -9
  6. package/dist/api/framework.d.ts +2 -0
  7. package/dist/api/framework.js +37 -0
  8. package/dist/api/http.js +11 -11
  9. package/dist/bin/vatts.js +50 -87
  10. package/dist/builder.js +196 -113
  11. package/dist/client/clientRouter.js +1 -1
  12. package/dist/global/global.d.ts +177 -117
  13. package/dist/helpers.d.ts +8 -0
  14. package/dist/helpers.js +8 -3
  15. package/dist/hotReload.d.ts +6 -0
  16. package/dist/hotReload.js +128 -19
  17. package/dist/index.js +29 -12
  18. package/dist/loaders.js +110 -31
  19. package/dist/react/BuildingPage.d.ts +2 -0
  20. package/dist/{client → react}/BuildingPage.js +43 -3
  21. package/dist/react/DefaultNotFound.d.ts +2 -0
  22. package/dist/react/DefaultNotFound.js +242 -0
  23. package/dist/{client → react}/DevIndicator.js +57 -17
  24. package/dist/{client → react}/ErrorModal.js +77 -29
  25. package/dist/{components → react}/Link.d.ts +2 -2
  26. package/dist/{global/global.js → react/Link.js} +15 -0
  27. package/dist/{client → react}/client.d.ts +3 -3
  28. package/dist/{client → react}/client.js +3 -3
  29. package/dist/{client → react}/entry.client.js +10 -8
  30. package/dist/{client → react}/image/Image.js +5 -2
  31. package/dist/react/renderer-react.d.ts +15 -0
  32. package/dist/react/renderer-react.js +371 -0
  33. package/dist/renderer.d.ts +5 -2
  34. package/dist/renderer.js +14 -349
  35. package/dist/router.d.ts +1 -1
  36. package/dist/router.js +14 -8
  37. package/dist/types.d.ts +1 -2
  38. package/dist/vue/App.vue +180 -0
  39. package/dist/vue/BuildingPage.vue +272 -0
  40. package/dist/vue/DefaultNotFound.vue +307 -0
  41. package/dist/vue/DevIndicator.vue +210 -0
  42. package/dist/vue/ErrorModal.vue +301 -0
  43. package/dist/vue/Link.vue +23 -0
  44. package/dist/vue/client.d.ts +7 -0
  45. package/dist/vue/client.js +34 -0
  46. package/dist/vue/entry.client.d.ts +6 -0
  47. package/dist/vue/entry.client.js +99 -0
  48. package/dist/vue/image/Image.vue +107 -0
  49. package/dist/vue/renderer.vue.d.ts +15 -0
  50. package/dist/vue/renderer.vue.js +506 -0
  51. package/package.json +50 -14
  52. package/dist/client/BuildingPage.d.ts +0 -1
  53. package/dist/client/DefaultNotFound.d.ts +0 -1
  54. package/dist/client/DefaultNotFound.js +0 -170
  55. package/dist/components/Link.js +0 -13
  56. /package/dist/{client → react}/DevIndicator.d.ts +0 -0
  57. /package/dist/{client → react}/ErrorModal.d.ts +0 -0
  58. /package/dist/{client → react}/entry.client.d.ts +0 -0
  59. /package/dist/{client → react}/image/Image.d.ts +0 -0
package/dist/builder.js CHANGED
@@ -15,6 +15,14 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
19
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
20
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
21
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
22
+ });
23
+ }
24
+ return path;
25
+ };
18
26
  const { rollup, watch: rollupWatch } = require('rollup');
19
27
  const path = require('path');
20
28
  const Console = require("./api/console").default;
@@ -27,6 +35,28 @@ const replace = require('@rollup/plugin-replace').default;
27
35
  const esbuild = require('rollup-plugin-esbuild').default;
28
36
  const jsonPlugin = require("@rollup/plugin-json").default;
29
37
  const { loadTsConfigPaths, resolveTsConfigAlias } = require('./tsconfigPaths');
38
+ // --- Helper de Detecção de Framework ---
39
+ // Helper para determinar o framework principal do projeto
40
+ function detectFramework(projectDir = process.cwd()) {
41
+ // 1. Tenta detectar pelo package.json (mais preciso e evita conflitos)
42
+ try {
43
+ const pkgPath = path.join(projectDir, 'package.json');
44
+ if (fs.existsSync(pkgPath)) {
45
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
46
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
47
+ // Prioridade explicita para React se estiver listado
48
+ if (deps.react || deps['react-dom'])
49
+ return 'react';
50
+ // Se tiver Vue e não React, é Vue
51
+ if (deps.vue || deps['nuxt'])
52
+ return 'vue';
53
+ }
54
+ }
55
+ catch (e) {
56
+ // Ignora erro de leitura
57
+ }
58
+ return 'react'; // Default fallback
59
+ }
30
60
  const tsconfigPathsPlugin = (projectDir = process.cwd()) => {
31
61
  const info = loadTsConfigPaths(projectDir);
32
62
  return {
@@ -85,7 +115,7 @@ const customPostCssPlugin = (isProduction) => {
85
115
  try {
86
116
  let postcss;
87
117
  try {
88
- postcss = require(path.join(projectDir, 'node_modules', 'postcss'));
118
+ postcss = require(__rewriteRelativeImportExtension(path.join(projectDir, 'node_modules', 'postcss')));
89
119
  }
90
120
  catch {
91
121
  try {
@@ -96,10 +126,7 @@ const customPostCssPlugin = (isProduction) => {
96
126
  }
97
127
  }
98
128
  if (postcss) {
99
- // OTIMIZAÇÃO DE RAM: Removido 'delete require.cache'.
100
- // Limpar o cache constantemente fragmenta a memória heap do V8 em processos longos (watch).
101
- // Se o usuário alterar o config, ele deve reiniciar o processo.
102
- const config = require(configPath);
129
+ const config = require(__rewriteRelativeImportExtension(configPath));
103
130
  const postcssConfig = config.default || config;
104
131
  const plugins = [];
105
132
  if (postcssConfig.plugins) {
@@ -108,10 +135,10 @@ const customPostCssPlugin = (isProduction) => {
108
135
  if (typeof p === 'string') {
109
136
  try {
110
137
  const resolved = require.resolve(p, { paths: [projectDir] });
111
- return require(resolved);
138
+ return require(__rewriteRelativeImportExtension(resolved));
112
139
  }
113
140
  catch {
114
- return require(p);
141
+ return require(__rewriteRelativeImportExtension(p));
115
142
  }
116
143
  }
117
144
  return p;
@@ -121,7 +148,7 @@ const customPostCssPlugin = (isProduction) => {
121
148
  for (const [name, options] of Object.entries(postcssConfig.plugins)) {
122
149
  try {
123
150
  const resolvedPath = require.resolve(name, { paths: [projectDir] });
124
- const pluginModule = require(resolvedPath);
151
+ const pluginModule = require(__rewriteRelativeImportExtension(resolvedPath));
125
152
  plugins.push(pluginModule(options || {}));
126
153
  }
127
154
  catch (e) {
@@ -142,73 +169,55 @@ const customPostCssPlugin = (isProduction) => {
142
169
  };
143
170
  return {
144
171
  name: 'custom-postcss-plugin',
145
- async resolveId(source, importer) {
146
- if (source.startsWith('\0custom-css:'))
172
+ async transform(code, id) {
173
+ // Intercepta arquivos CSS e requests virtuais de estilo do Vue (que terminam em .css)
174
+ if (!id.endsWith('.css'))
147
175
  return null;
148
- if (source.endsWith('.css')) {
149
- const resolution = await this.resolve(source, importer, { skipSelf: true });
150
- if (resolution && resolution.id) {
151
- if (resolution.id.startsWith('\0custom-css:'))
152
- return resolution.id;
153
- return `\0custom-css:${resolution.id}`;
154
- }
155
- }
156
- return null;
157
- },
158
- async load(id) {
159
- if (id.startsWith('\0custom-css:')) {
160
- let filePath = id.slice('\0custom-css:'.length);
161
- while (filePath.startsWith('\0custom-css:')) {
162
- filePath = filePath.slice('\0custom-css:'.length);
176
+ const processor = await initPostCss(process.cwd());
177
+ let processedCss = code;
178
+ if (processor) {
179
+ try {
180
+ const result = await processor.process(code, {
181
+ from: id,
182
+ to: id,
183
+ map: false // Mapas inline ou não, melhor manter simples aqui
184
+ });
185
+ processedCss = result.css;
163
186
  }
164
- const cssContent = await fs.promises.readFile(filePath, 'utf8');
165
- // Usa o processador em cache ou inicializa se for a primeira vez
166
- const processor = await initPostCss(process.cwd());
167
- let processedCss = cssContent;
168
- if (processor) {
169
- try {
170
- const result = await processor.process(cssContent, {
171
- from: filePath,
172
- to: filePath
173
- });
174
- processedCss = result.css;
175
- }
176
- catch (e) {
177
- Console.warn(`PostCSS process error:`, e.message);
178
- }
187
+ catch (e) {
188
+ Console.warn(`PostCSS process error:`, e.message);
179
189
  }
180
- // OTIMIZAÇÃO: Emite arquivo físico sempre que possível.
181
- // Strings gigantes de CSS inline consomem muita RAM no bundle JS.
182
- const referenceId = this.emitFile({
183
- type: 'asset',
184
- name: path.basename(filePath),
185
- source: processedCss
186
- });
187
- // Lógica unificada: Usa arquivo externo tanto em Dev quanto Prod.
188
- // Isso libera a memória que seria usada para stringificar o CSS dentro do JS.
189
- // FIX: O Rollup pode retornar um objeto URL ao invés de string. String() força a conversão.
190
- return `
191
- const cssUrl = String(import.meta.ROLLUP_FILE_URL_${referenceId});
192
- if (typeof document !== 'undefined') {
193
- const link = document.createElement('link');
194
- link.rel = 'stylesheet';
195
- link.href = cssUrl;
196
- document.head.appendChild(link);
197
- }
198
- export default cssUrl;
199
- `;
200
190
  }
201
- return null;
191
+ // Emite o arquivo CSS processado como asset
192
+ // Remove query params do Vue (ex: ?vue&type=style...) para gerar um nome de arquivo limpo
193
+ const cleanName = path.basename(id).split('?')[0];
194
+ const referenceId = this.emitFile({
195
+ type: 'asset',
196
+ name: cleanName,
197
+ source: processedCss
198
+ });
199
+ // Retorna o módulo JS que injeta o CSS via <link>
200
+ // FIX: Retorna um objeto com 'code' e 'map' para evitar o aviso "Sourcemap is likely to be incorrect"
201
+ return {
202
+ code: `
203
+ const cssUrl = String(import.meta.ROLLUP_FILE_URL_${referenceId});
204
+ if (typeof document !== 'undefined') {
205
+ const link = document.createElement('link');
206
+ link.rel = 'stylesheet';
207
+ link.href = cssUrl;
208
+ document.head.appendChild(link);
209
+ }
210
+ export default cssUrl;
211
+ `,
212
+ map: { mappings: '' }
213
+ };
202
214
  }
203
215
  };
204
216
  };
205
217
  /**
206
218
  * Plugin Inteligente para Assets (Otimizado para RAM)
207
- * - Agora utiliza emissão de arquivos também em DEV para arquivos grandes.
208
219
  */
209
220
  const smartAssetPlugin = (isProduction) => {
210
- // 4KB - Arquivos maiores que isso viram referência externa.
211
- // Manter isso baixo economiza MUITA RAM, pois evita strings Base64 gigantes no JS.
212
221
  const INLINE_LIMIT = 4096;
213
222
  return {
214
223
  name: 'smart-asset-loader',
@@ -231,19 +240,17 @@ const smartAssetPlugin = (isProduction) => {
231
240
  const type = mimeTypes[ext];
232
241
  if (!type)
233
242
  return null;
234
- // Text files always strings (geralmente pequenos)
235
243
  if (type === 'txt') {
236
244
  const content = await fs.promises.readFile(cleanId, 'utf8');
237
245
  return `export default ${JSON.stringify(content)};`;
238
246
  }
239
247
  let buffer = await fs.promises.readFile(cleanId);
240
248
  const size = buffer.length;
241
- // Tratamento especial para SVG (inline SVG vs URL)
242
249
  if (type === 'svg') {
243
250
  if (size < INLINE_LIMIT) {
244
251
  const content = buffer.toString('utf8');
245
252
  const base64 = buffer.toString('base64');
246
- buffer = null; // GC Hint
253
+ buffer = null;
247
254
  return `
248
255
  export default "data:image/svg+xml;base64,${base64}";
249
256
  export const svgContent = ${JSON.stringify(content)};
@@ -256,21 +263,16 @@ const smartAssetPlugin = (isProduction) => {
256
263
  source: buffer
257
264
  });
258
265
  const content = buffer.toString('utf8');
259
- buffer = null; // GC Hint
260
- // FIX: O Rollup pode retornar um objeto URL. String() resolve o erro de startsWith.
266
+ buffer = null;
261
267
  return `
262
268
  export default String(import.meta.ROLLUP_FILE_URL_${referenceId});
263
269
  export const svgContent = ${JSON.stringify(content)};
264
270
  `;
265
271
  }
266
272
  }
267
- // Para outros assets:
268
- // Se for pequeno, Base64 (reduz requests HTTP)
269
- // Se for grande, Arquivo (reduz uso de RAM e tamanho do bundle JS)
270
- // Essa lógica agora aplica para DEV e PROD. Base64 em Dev para arquivos grandes era o vilão da RAM.
271
273
  if (size < INLINE_LIMIT) {
272
274
  const base64 = buffer.toString('base64');
273
- buffer = null; // Libera memória do buffer bruto imediatamente
275
+ buffer = null;
274
276
  return `export default "data:${type};base64,${base64}";`;
275
277
  }
276
278
  else {
@@ -279,69 +281,155 @@ const smartAssetPlugin = (isProduction) => {
279
281
  name: path.basename(cleanId),
280
282
  source: buffer
281
283
  });
282
- buffer = null; // Libera memória
283
- // FIX: O Rollup pode retornar um objeto URL. String() resolve o erro de startsWith.
284
+ buffer = null;
284
285
  return `export default String(import.meta.ROLLUP_FILE_URL_${referenceId});`;
285
286
  }
286
287
  }
287
288
  };
288
289
  };
289
290
  /**
290
- * Gera a configuração base do Rollup
291
+ * Gera a configuração base do Rollup (Agora Async e Estrita)
291
292
  */
292
- function createRollupConfig(entryPoint, outdir, isProduction) {
293
+ async function createRollupConfig(entryPoint, outdir, isProduction) {
294
+ // Detecta Framework de forma exclusiva e robusta
295
+ const framework = detectFramework();
296
+ const hasVue = framework === 'vue';
297
+ const hasReact = framework === 'react';
298
+ // Define variáveis de ambiente
299
+ const replaceValues = {
300
+ 'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
301
+ 'process.env.PORT': JSON.stringify(process.vatts.port || 3000)
302
+ };
303
+ // --- LÓGICA VUE ESTRITA ---
304
+ let vuePlugin = null;
305
+ if (hasVue) {
306
+ replaceValues['__VUE_OPTIONS_API__'] = JSON.stringify(true);
307
+ replaceValues['__VUE_PROD_DEVTOOLS__'] = JSON.stringify(!isProduction);
308
+ try {
309
+ let vuePkg;
310
+ try {
311
+ vuePkg = require('rollup-plugin-vue');
312
+ }
313
+ catch (e) {
314
+ if (e.code === 'ERR_REQUIRE_ESM') {
315
+ vuePkg = await import('rollup-plugin-vue');
316
+ }
317
+ else {
318
+ throw e;
319
+ }
320
+ }
321
+ const vueFactory = vuePkg.default || vuePkg;
322
+ if (typeof vueFactory === 'function') {
323
+ vuePlugin = vueFactory({
324
+ compilerOptions: {
325
+ isCustomElement: (tag) => tag.includes('-')
326
+ }
327
+ });
328
+ }
329
+ }
330
+ catch (e) {
331
+ Console.warn("Vue detected but failed to load rollup-plugin-vue:", e.message);
332
+ }
333
+ }
334
+ // --- CONFIGURAÇÃO DE EXTENSÕES ---
335
+ // Fix: Prioriza .vue se for um projeto Vue para evitar que o NodeResolve pegue artefatos gerados (como .vue.js do Volar)
336
+ // ao invés do arquivo fonte .vue.
337
+ let extensions = ['.mjs', '.js', '.json', '.node', '.jsx', '.tsx', '.ts'];
338
+ if (hasVue) {
339
+ // Coloca .vue no INÍCIO da lista
340
+ extensions = ['.vue', ...extensions];
341
+ }
342
+ // --- CONFIGURAÇÃO DO ESBUILD ---
343
+ // SEPARAÇÃO: Regex específico para cada framework.
344
+ // FIX ERRO VUE: O Regex do Vue inclui os arquivos virtuais `?vue`,
345
+ // mas o loader '.vue': 'ts' foi removido para evitar conflito com o plugin do Vue.
346
+ let esbuildInclude;
347
+ if (hasVue) {
348
+ esbuildInclude = /\.[jt]sx?$|\.vue\?vue/;
349
+ }
350
+ else {
351
+ esbuildInclude = /\.[jt]sx?$/; // React/Vanilla: ignora arquivos virtuais do Vue
352
+ }
353
+ const esbuildLoaders = {
354
+ '.js': 'jsx',
355
+ '.ts': 'ts',
356
+ '.tsx': 'tsx',
357
+ // RESTAURADO: .vue para ts. Isso é NECESSÁRIO para processar blocos <script lang="ts">
358
+ // Se houver erros do tipo __VLS_, o plugin 'block-volar-artifacts' abaixo deve resolver.
359
+ '.vue': 'ts'
360
+ };
361
+ // No Vue, partes do arquivo podem virar TS, mas isso é pego pela extensão do arquivo virtual,
362
+ // não precisamos forçar no loader geral.
293
363
  return {
294
364
  input: entryPoint,
295
365
  external: nodeBuiltIns,
296
- // Otimização: Treeshake limpa memória removendo nós da AST não usados
297
366
  treeshake: {
298
- moduleSideEffects: 'no-external', // Mais agressivo, economiza memória
367
+ moduleSideEffects: 'no-external',
299
368
  preset: isProduction ? 'recommended' : 'smallest'
300
369
  },
301
- // Cache desativado em DEV conforme solicitado anteriormente,
302
- // o que ajuda na RAM pois não mantém a AST antiga em memória.
303
370
  cache: isProduction ? true : false,
304
371
  perf: false,
305
- // Limita execuções paralelas de leitura de arquivo internas do Rollup
306
372
  maxParallelFileOps: 20,
307
373
  plugins: [
308
374
  replace({
309
375
  preventAssignment: true,
310
- values: {
311
- 'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
312
- 'proccess.env.PORT': JSON.stringify(process.vatts.port || 3000)
313
- }
376
+ values: replaceValues
314
377
  }),
315
378
  tsconfigPathsPlugin(process.cwd()),
379
+ // NOVO: Blocker agressivo para artefatos gerados pelo Volar/TS (.vue.js, .vue.d.ts)
380
+ // Isso previne que o build tente empacotar arquivos temporários de tipagem como se fossem código fonte.
381
+ {
382
+ name: 'block-volar-artifacts',
383
+ load(id) {
384
+ // Ignora arquivos que terminam em .vue.js, .vue.ts, ou .vue.d.ts
385
+ // Esses arquivos frequentemente contêm código "virtual" (__VLS_...) que causa erros em runtime.
386
+ if (/\.vue\.(js|ts|d\.ts|map)$/.test(id)) {
387
+ return 'export default {};';
388
+ }
389
+ return null;
390
+ }
391
+ },
392
+ // NOVO: Blocker para artefatos Vue (.vue e .vue.js) em projetos React
393
+ // Impede que arquivos compilados do Vue quebrem o build React
394
+ {
395
+ name: 'block-vue-artifacts',
396
+ load(id) {
397
+ // Verifica se não estamos no Vue e se o arquivo é um artefato Vue
398
+ if (!hasVue && (id.endsWith('.vue') || id.endsWith('.vue.js'))) {
399
+ // Retorna módulo vazio para "matar" o arquivo e impedir erros de runtime
400
+ return 'export default {};';
401
+ }
402
+ return null;
403
+ }
404
+ },
316
405
  nodeResolve({
317
- extensions: ['.mjs', '.js', '.json', '.node', '.jsx', '.tsx', '.ts'],
406
+ extensions, // Agora com .vue prioritário se hasVue for true
318
407
  preferBuiltins: true,
319
408
  browser: true,
320
- dedupe: ['react', 'react-dom']
409
+ dedupe: hasReact ? ['react', 'react-dom'] : (hasVue ? ['vue'] : [])
321
410
  }),
411
+ // CRÍTICO: Injeta plugin do Vue APENAS se for Vue e ANTES de commonjs/esbuild.
412
+ ...(hasVue && vuePlugin ? [vuePlugin] : []),
322
413
  commonjs({
323
414
  sourceMap: !isProduction,
324
415
  requireReturnsDefault: 'auto',
325
- // Ignora try-catch dinâmicos para economizar análise
326
416
  ignoreTryCatch: true
327
417
  }),
328
418
  markdownPlugin(),
329
- // PostCSS Otimizado
330
419
  customPostCssPlugin(isProduction),
331
- // Assets Otimizados (menos Base64)
332
420
  smartAssetPlugin(isProduction),
333
421
  jsonPlugin(),
334
422
  esbuild({
335
- include: /\.[jt]sx?$/,
336
- exclude: /node_modules/,
423
+ include: esbuildInclude,
424
+ exclude: /node_modules/, // Se for React, arquivos .vue serão ignorados pelo regex do include
337
425
  sourceMap: !isProduction,
338
426
  minify: isProduction,
339
- legalComments: 'none', // Remove comentários para limpar buffer
427
+ legalComments: 'none',
340
428
  treeShaking: isProduction,
341
- target: isProduction ? 'es2020' : 'esnext',
429
+ target: 'esnext',
342
430
  jsx: 'automatic',
343
431
  define: { __VERSION__: '"1.0.0"' },
344
- loaders: { '.js': 'jsx' }
432
+ loaders: esbuildLoaders
345
433
  })
346
434
  ],
347
435
  onwarn(warning, warn) {
@@ -349,7 +437,6 @@ function createRollupConfig(entryPoint, outdir, isProduction) {
349
437
  return;
350
438
  if (warning.code === 'THIS_IS_UNDEFINED')
351
439
  return;
352
- // Ignora avisos circulares comuns que enchem o log/buffer
353
440
  if (warning.code === 'CIRCULAR_DEPENDENCY' && warning.message.includes('node_modules'))
354
441
  return;
355
442
  warn(warning);
@@ -362,7 +449,7 @@ function createRollupConfig(entryPoint, outdir, isProduction) {
362
449
  async function buildWithChunks(entryPoint, outdir, isProduction = false) {
363
450
  await cleanDirectoryExcept(outdir, 'temp');
364
451
  try {
365
- const inputOptions = createRollupConfig(entryPoint, outdir, isProduction);
452
+ const inputOptions = await createRollupConfig(entryPoint, outdir, isProduction);
366
453
  const outputOptions = {
367
454
  dir: outdir,
368
455
  format: 'es',
@@ -370,7 +457,6 @@ async function buildWithChunks(entryPoint, outdir, isProduction = false) {
370
457
  chunkFileNames: 'chunks/[name]-[hash].js',
371
458
  assetFileNames: 'assets/[name]-[hash][extname]',
372
459
  sourcemap: !isProduction,
373
- // Compacta output para economizar memória de escrita
374
460
  compact: isProduction,
375
461
  manualChunks(id) {
376
462
  if (id.includes('node_modules')) {
@@ -378,7 +464,10 @@ async function buildWithChunks(entryPoint, outdir, isProduction = false) {
378
464
  if (/\/node_modules\/(react|react-dom|scheduler|prop-types|loose-envify|object-assign)\//.test(normalizedId)) {
379
465
  return 'vendor-react';
380
466
  }
381
- if (id.includes('framer-motion') || id.includes('@radix-ui')) {
467
+ if (/\/node_modules\/(vue|@vue)\//.test(normalizedId)) {
468
+ return 'vendor-vue';
469
+ }
470
+ if (id.includes('framer-motion') || id.includes('@radix-ui') || id.includes('@headlessui')) {
382
471
  return 'vendor-ui';
383
472
  }
384
473
  if (id.includes('lodash') || id.includes('date-fns') || id.includes('axios')) {
@@ -390,7 +479,7 @@ async function buildWithChunks(entryPoint, outdir, isProduction = false) {
390
479
  };
391
480
  const bundle = await rollup(inputOptions);
392
481
  await bundle.write(outputOptions);
393
- await bundle.close(); // Importante fechar para liberar memória
482
+ await bundle.close();
394
483
  }
395
484
  catch (error) {
396
485
  Console.error('An error occurred while building with chunks:', error);
@@ -404,14 +493,14 @@ async function build(entryPoint, outfile, isProduction = false) {
404
493
  const outdir = path.dirname(outfile);
405
494
  await cleanDirectoryExcept(outdir, 'temp');
406
495
  try {
407
- const inputOptions = createRollupConfig(entryPoint, outdir, isProduction);
496
+ const inputOptions = await createRollupConfig(entryPoint, outdir, isProduction);
408
497
  const outputOptions = {
409
498
  file: outfile,
410
499
  format: 'iife',
411
500
  name: 'Vattsjs',
412
501
  sourcemap: !isProduction,
413
502
  inlineDynamicImports: true,
414
- compact: true // Ajuda na RAM
503
+ compact: true
415
504
  };
416
505
  const bundle = await rollup(inputOptions);
417
506
  await bundle.write(outputOptions);
@@ -433,7 +522,6 @@ function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
433
522
  if (event.code === 'START') {
434
523
  currentBuildId += 1;
435
524
  lastStartedBuildId = currentBuildId;
436
- // Dica pro V8 limpar lixo antes de começar um build pesado
437
525
  if (global.gc) {
438
526
  try {
439
527
  global.gc();
@@ -460,7 +548,6 @@ function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
460
548
  resolveFirstBuild();
461
549
  }
462
550
  if (event.code === 'BUNDLE_END') {
463
- // CRÍTICO: Fechar o bundle libera a memória dos módulos
464
551
  event.result.close();
465
552
  }
466
553
  if (event.code === 'END') {
@@ -488,7 +575,7 @@ function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
488
575
  async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
489
576
  await cleanDirectoryExcept(outdir, 'temp');
490
577
  try {
491
- const inputOptions = createRollupConfig(entryPoint, outdir, false);
578
+ const inputOptions = await createRollupConfig(entryPoint, outdir, false);
492
579
  const outputOptions = {
493
580
  dir: outdir,
494
581
  format: 'es',
@@ -502,7 +589,6 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
502
589
  exclude: 'node_modules/**',
503
590
  clearScreen: false,
504
591
  skipWrite: false,
505
- // Atraso curto para evitar múltiplos rebuilds rápidos que comem CPU/RAM
506
592
  buildDelay: 100
507
593
  }
508
594
  };
@@ -523,7 +609,7 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
523
609
  async function watch(entryPoint, outfile, hotReloadManager = null) {
524
610
  const outdir = path.dirname(outfile);
525
611
  try {
526
- const inputOptions = createRollupConfig(entryPoint, outdir, false);
612
+ const inputOptions = await createRollupConfig(entryPoint, outdir, false);
527
613
  const outputOptions = {
528
614
  file: outfile,
529
615
  format: 'es',
@@ -555,9 +641,6 @@ async function cleanDirectoryExcept(dirPath, excludeFolder) {
555
641
  return;
556
642
  const excludes = Array.isArray(excludeFolder) ? excludeFolder : [excludeFolder];
557
643
  const items = await readdir(dirPath);
558
- // OTIMIZAÇÃO: Loop sequencial ao invés de Promise.all.
559
- // Promise.all é mais rápido, mas cria dezenas/centenas de Promises simultâneas na RAM.
560
- // O loop sequencial é mais gentil com o Garbage Collector.
561
644
  for (const item of items) {
562
645
  if (excludes.includes(item))
563
646
  continue;
@@ -567,7 +650,7 @@ async function cleanDirectoryExcept(dirPath, excludeFolder) {
567
650
  await rm(itemPath, { recursive: info.isDirectory(), force: true });
568
651
  }
569
652
  catch (e) {
570
- // Ignora erro se arquivo sumir durante o loop
653
+ // Ignora erro se arquivo sumir
571
654
  }
572
655
  }
573
656
  }
@@ -18,8 +18,8 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.router = exports.Router = void 0;
20
20
  class Router {
21
+ listeners = new Set();
21
22
  constructor() {
22
- this.listeners = new Set();
23
23
  // Só adiciona listener no lado do cliente
24
24
  if (typeof window !== 'undefined') {
25
25
  window.addEventListener('popstate', () => {