vatts 1.0.2-alpha.1 → 1.0.2-alpha.3
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/builder.js +110 -123
- package/dist/client/clientRouter.js +0 -1
- package/dist/client/entry.client.js +7 -7
- package/dist/env/env.d.ts +5 -0
- package/dist/env/env.js +69 -0
- package/dist/helpers.js +21 -18
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -11
- package/dist/renderer.js +1 -1
- package/dist/types.d.ts +7 -4
- package/package.json +1 -1
package/dist/builder.js
CHANGED
|
@@ -58,14 +58,14 @@ const markdownPlugin = () => {
|
|
|
58
58
|
if (id.endsWith('.md')) {
|
|
59
59
|
return {
|
|
60
60
|
code: `export default ${JSON.stringify(code)};`,
|
|
61
|
-
map: null
|
|
61
|
+
map: null // Null map economiza memória se não precisa debugar markdown
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
};
|
|
67
67
|
/**
|
|
68
|
-
* Plugin para CSS/PostCSS Manual (
|
|
68
|
+
* Plugin para CSS/PostCSS Manual (Otimizado para RAM)
|
|
69
69
|
*/
|
|
70
70
|
const customPostCssPlugin = (isProduction) => {
|
|
71
71
|
let cachedProcessor = null;
|
|
@@ -95,7 +95,9 @@ const customPostCssPlugin = (isProduction) => {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
if (postcss) {
|
|
98
|
-
delete require.cache
|
|
98
|
+
// OTIMIZAÇÃO DE RAM: Removido 'delete require.cache'.
|
|
99
|
+
// Limpar o cache constantemente fragmenta a memória heap do V8 em processos longos (watch).
|
|
100
|
+
// Se o usuário alterar o config, ele deve reiniciar o processo.
|
|
99
101
|
const config = require(configPath);
|
|
100
102
|
const postcssConfig = config.default || config;
|
|
101
103
|
const plugins = [];
|
|
@@ -174,36 +176,24 @@ const customPostCssPlugin = (isProduction) => {
|
|
|
174
176
|
Console.warn(`PostCSS process error:`, e.message);
|
|
175
177
|
}
|
|
176
178
|
}
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
// Isso mantém compatibilidade (não quebra o app) mas usa arquivo externo
|
|
187
|
-
return `
|
|
188
|
-
const cssUrl = import.meta.ROLLUP_FILE_URL_${referenceId};
|
|
189
|
-
if (typeof document !== 'undefined') {
|
|
190
|
-
const link = document.createElement('link');
|
|
191
|
-
link.rel = 'stylesheet';
|
|
192
|
-
link.href = cssUrl;
|
|
193
|
-
document.head.appendChild(link);
|
|
194
|
-
}
|
|
195
|
-
export default cssUrl;
|
|
196
|
-
`;
|
|
197
|
-
}
|
|
198
|
-
// Modo DEV (Inline para Hot Reload mais rápido)
|
|
179
|
+
// OTIMIZAÇÃO: Emite arquivo físico sempre que possível.
|
|
180
|
+
// Strings gigantes de CSS inline consomem muita RAM no bundle JS.
|
|
181
|
+
const referenceId = this.emitFile({
|
|
182
|
+
type: 'asset',
|
|
183
|
+
name: path.basename(filePath),
|
|
184
|
+
source: processedCss
|
|
185
|
+
});
|
|
186
|
+
// Lógica unificada: Usa arquivo externo tanto em Dev quanto Prod.
|
|
187
|
+
// Isso libera a memória que seria usada para stringificar o CSS dentro do JS.
|
|
199
188
|
return `
|
|
200
|
-
const
|
|
189
|
+
const cssUrl = import.meta.ROLLUP_FILE_URL_${referenceId};
|
|
201
190
|
if (typeof document !== 'undefined') {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
191
|
+
const link = document.createElement('link');
|
|
192
|
+
link.rel = 'stylesheet';
|
|
193
|
+
link.href = cssUrl;
|
|
194
|
+
document.head.appendChild(link);
|
|
205
195
|
}
|
|
206
|
-
export default
|
|
196
|
+
export default cssUrl;
|
|
207
197
|
`;
|
|
208
198
|
}
|
|
209
199
|
return null;
|
|
@@ -211,12 +201,13 @@ const customPostCssPlugin = (isProduction) => {
|
|
|
211
201
|
};
|
|
212
202
|
};
|
|
213
203
|
/**
|
|
214
|
-
* Plugin Inteligente para Assets (
|
|
215
|
-
* -
|
|
216
|
-
* - Prod: Arquivos > 4KB viram URL (Melhora LCP), < 4KB Base64 (Menos requests)
|
|
204
|
+
* Plugin Inteligente para Assets (Otimizado para RAM)
|
|
205
|
+
* - Agora utiliza emissão de arquivos também em DEV para arquivos grandes.
|
|
217
206
|
*/
|
|
218
207
|
const smartAssetPlugin = (isProduction) => {
|
|
219
|
-
|
|
208
|
+
// 4KB - Arquivos maiores que isso viram referência externa.
|
|
209
|
+
// Manter isso baixo economiza MUITA RAM, pois evita strings Base64 gigantes no JS.
|
|
210
|
+
const INLINE_LIMIT = 4096;
|
|
220
211
|
return {
|
|
221
212
|
name: 'smart-asset-loader',
|
|
222
213
|
async load(id) {
|
|
@@ -238,42 +229,23 @@ const smartAssetPlugin = (isProduction) => {
|
|
|
238
229
|
const type = mimeTypes[ext];
|
|
239
230
|
if (!type)
|
|
240
231
|
return null;
|
|
241
|
-
// Text files always strings
|
|
232
|
+
// Text files always strings (geralmente pequenos)
|
|
242
233
|
if (type === 'txt') {
|
|
243
234
|
const content = await fs.promises.readFile(cleanId, 'utf8');
|
|
244
235
|
return `export default ${JSON.stringify(content)};`;
|
|
245
236
|
}
|
|
246
|
-
|
|
237
|
+
let buffer = await fs.promises.readFile(cleanId);
|
|
247
238
|
const size = buffer.length;
|
|
248
|
-
//
|
|
249
|
-
if (
|
|
250
|
-
// SVG: Se for pequeno inlina, se grande emite arquivo
|
|
251
|
-
if (type === 'svg') {
|
|
252
|
-
if (size < INLINE_LIMIT) {
|
|
253
|
-
const content = buffer.toString('utf8');
|
|
254
|
-
const base64 = buffer.toString('base64');
|
|
255
|
-
return `
|
|
256
|
-
export default "data:image/svg+xml;base64,${base64}";
|
|
257
|
-
export const svgContent = ${JSON.stringify(content)};
|
|
258
|
-
`;
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
// Emite arquivo físico
|
|
262
|
-
const referenceId = this.emitFile({
|
|
263
|
-
type: 'asset',
|
|
264
|
-
name: path.basename(cleanId),
|
|
265
|
-
source: buffer
|
|
266
|
-
});
|
|
267
|
-
const content = buffer.toString('utf8');
|
|
268
|
-
return `
|
|
269
|
-
export default import.meta.ROLLUP_FILE_URL_${referenceId};
|
|
270
|
-
export const svgContent = ${JSON.stringify(content)};
|
|
271
|
-
`;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
// Outros assets
|
|
239
|
+
// Tratamento especial para SVG (inline SVG vs URL)
|
|
240
|
+
if (type === 'svg') {
|
|
275
241
|
if (size < INLINE_LIMIT) {
|
|
276
|
-
|
|
242
|
+
const content = buffer.toString('utf8');
|
|
243
|
+
const base64 = buffer.toString('base64');
|
|
244
|
+
buffer = null; // GC Hint
|
|
245
|
+
return `
|
|
246
|
+
export default "data:image/svg+xml;base64,${base64}";
|
|
247
|
+
export const svgContent = ${JSON.stringify(content)};
|
|
248
|
+
`;
|
|
277
249
|
}
|
|
278
250
|
else {
|
|
279
251
|
const referenceId = this.emitFile({
|
|
@@ -281,19 +253,32 @@ const smartAssetPlugin = (isProduction) => {
|
|
|
281
253
|
name: path.basename(cleanId),
|
|
282
254
|
source: buffer
|
|
283
255
|
});
|
|
284
|
-
|
|
256
|
+
const content = buffer.toString('utf8');
|
|
257
|
+
buffer = null; // GC Hint
|
|
258
|
+
return `
|
|
259
|
+
export default import.meta.ROLLUP_FILE_URL_${referenceId};
|
|
260
|
+
export const svgContent = ${JSON.stringify(content)};
|
|
261
|
+
`;
|
|
285
262
|
}
|
|
286
263
|
}
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
264
|
+
// Para outros assets:
|
|
265
|
+
// Se for pequeno, Base64 (reduz requests HTTP)
|
|
266
|
+
// Se for grande, Arquivo (reduz uso de RAM e tamanho do bundle JS)
|
|
267
|
+
// Essa lógica agora aplica para DEV e PROD. Base64 em Dev para arquivos grandes era o vilão da RAM.
|
|
268
|
+
if (size < INLINE_LIMIT) {
|
|
290
269
|
const base64 = buffer.toString('base64');
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
270
|
+
buffer = null; // Libera memória do buffer bruto imediatamente
|
|
271
|
+
return `export default "data:${type};base64,${base64}";`;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
const referenceId = this.emitFile({
|
|
275
|
+
type: 'asset',
|
|
276
|
+
name: path.basename(cleanId),
|
|
277
|
+
source: buffer
|
|
278
|
+
});
|
|
279
|
+
buffer = null; // Libera memória
|
|
280
|
+
return `export default import.meta.ROLLUP_FILE_URL_${referenceId};`;
|
|
295
281
|
}
|
|
296
|
-
return `export default "data:${type};base64,${buffer.toString('base64')}";`;
|
|
297
282
|
}
|
|
298
283
|
};
|
|
299
284
|
};
|
|
@@ -303,25 +288,25 @@ const smartAssetPlugin = (isProduction) => {
|
|
|
303
288
|
function createRollupConfig(entryPoint, outdir, isProduction) {
|
|
304
289
|
return {
|
|
305
290
|
input: entryPoint,
|
|
306
|
-
// Para evitar bare imports no browser (sem import map), em DEV também bundle React/ReactDOM.
|
|
307
|
-
// O HMR evita "Invalid hook call" removendo o script antigo e recarregando main.js.
|
|
308
291
|
external: nodeBuiltIns,
|
|
309
|
-
// Otimização:
|
|
310
|
-
treeshake:
|
|
311
|
-
|
|
312
|
-
|
|
292
|
+
// Otimização: Treeshake limpa memória removendo nós da AST não usados
|
|
293
|
+
treeshake: {
|
|
294
|
+
moduleSideEffects: 'no-external', // Mais agressivo, economiza memória
|
|
295
|
+
preset: isProduction ? 'recommended' : 'smallest'
|
|
296
|
+
},
|
|
297
|
+
// Cache desativado em DEV conforme solicitado anteriormente,
|
|
298
|
+
// o que ajuda na RAM pois não mantém a AST antiga em memória.
|
|
313
299
|
cache: isProduction ? true : false,
|
|
314
300
|
perf: false,
|
|
301
|
+
// Limita execuções paralelas de leitura de arquivo internas do Rollup
|
|
302
|
+
maxParallelFileOps: 20,
|
|
315
303
|
plugins: [
|
|
316
|
-
// CRÍTICO: 'replace' deve vir PRIMEIRO para injetar NODE_ENV antes que
|
|
317
|
-
// libs como React decidam qual bundle importar.
|
|
318
304
|
replace({
|
|
319
305
|
preventAssignment: true,
|
|
320
306
|
values: {
|
|
321
307
|
'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development')
|
|
322
308
|
}
|
|
323
309
|
}),
|
|
324
|
-
// Precisa vir antes do nodeResolve
|
|
325
310
|
tsconfigPathsPlugin(process.cwd()),
|
|
326
311
|
nodeResolve({
|
|
327
312
|
extensions: ['.mjs', '.js', '.json', '.node', '.jsx', '.tsx', '.ts'],
|
|
@@ -331,20 +316,21 @@ function createRollupConfig(entryPoint, outdir, isProduction) {
|
|
|
331
316
|
}),
|
|
332
317
|
commonjs({
|
|
333
318
|
sourceMap: !isProduction,
|
|
334
|
-
requireReturnsDefault: 'auto'
|
|
319
|
+
requireReturnsDefault: 'auto',
|
|
320
|
+
// Ignora try-catch dinâmicos para economizar análise
|
|
321
|
+
ignoreTryCatch: true
|
|
335
322
|
}),
|
|
336
323
|
markdownPlugin(),
|
|
337
|
-
//
|
|
324
|
+
// PostCSS Otimizado
|
|
338
325
|
customPostCssPlugin(isProduction),
|
|
339
|
-
//
|
|
326
|
+
// Assets Otimizados (menos Base64)
|
|
340
327
|
smartAssetPlugin(isProduction),
|
|
341
328
|
esbuild({
|
|
342
329
|
include: /\.[jt]sx?$/,
|
|
343
330
|
exclude: /node_modules/,
|
|
344
331
|
sourceMap: !isProduction,
|
|
345
332
|
minify: isProduction,
|
|
346
|
-
//
|
|
347
|
-
legalComments: isProduction ? 'none' : 'eof',
|
|
333
|
+
legalComments: 'none', // Remove comentários para limpar buffer
|
|
348
334
|
treeShaking: isProduction,
|
|
349
335
|
target: isProduction ? 'es2020' : 'esnext',
|
|
350
336
|
jsx: 'automatic',
|
|
@@ -357,6 +343,9 @@ function createRollupConfig(entryPoint, outdir, isProduction) {
|
|
|
357
343
|
return;
|
|
358
344
|
if (warning.code === 'THIS_IS_UNDEFINED')
|
|
359
345
|
return;
|
|
346
|
+
// Ignora avisos circulares comuns que enchem o log/buffer
|
|
347
|
+
if (warning.code === 'CIRCULAR_DEPENDENCY' && warning.message.includes('node_modules'))
|
|
348
|
+
return;
|
|
360
349
|
warn(warning);
|
|
361
350
|
}
|
|
362
351
|
};
|
|
@@ -371,39 +360,31 @@ async function buildWithChunks(entryPoint, outdir, isProduction = false) {
|
|
|
371
360
|
const outputOptions = {
|
|
372
361
|
dir: outdir,
|
|
373
362
|
format: 'es',
|
|
374
|
-
// Padrão de nomes mantido, mas com estrutura para vários arquivos
|
|
375
363
|
entryFileNames: isProduction ? 'main-[hash].js' : 'main.js',
|
|
376
364
|
chunkFileNames: 'chunks/[name]-[hash].js',
|
|
377
365
|
assetFileNames: 'assets/[name]-[hash][extname]',
|
|
378
366
|
sourcemap: !isProduction,
|
|
379
|
-
//
|
|
367
|
+
// Compacta output para economizar memória de escrita
|
|
368
|
+
compact: isProduction,
|
|
380
369
|
manualChunks(id) {
|
|
381
370
|
if (id.includes('node_modules')) {
|
|
382
|
-
// Normaliza separadores para garantir funcionamento em Windows/Linux
|
|
383
371
|
const normalizedId = id.replace(/\\/g, '/');
|
|
384
|
-
// React Core isolado
|
|
385
|
-
// IMPORTANTE: Uso de Regex para garantir que pegamos APENAS os pacotes do core
|
|
386
|
-
// e não pacotes que tenham 'react' no nome (ex: react-router, react-icons),
|
|
387
|
-
// pois isso causa dependências circulares com o chunk 'vendor'.
|
|
388
372
|
if (/\/node_modules\/(react|react-dom|scheduler|prop-types|loose-envify|object-assign)\//.test(normalizedId)) {
|
|
389
373
|
return 'vendor-react';
|
|
390
374
|
}
|
|
391
|
-
// UI Libs comuns (opcional, pode ajustar conforme necessidade)
|
|
392
375
|
if (id.includes('framer-motion') || id.includes('@radix-ui')) {
|
|
393
376
|
return 'vendor-ui';
|
|
394
377
|
}
|
|
395
|
-
// Utils comuns
|
|
396
378
|
if (id.includes('lodash') || id.includes('date-fns') || id.includes('axios')) {
|
|
397
379
|
return 'vendor-utils';
|
|
398
380
|
}
|
|
399
|
-
// Resto das dependências
|
|
400
381
|
return 'vendor';
|
|
401
382
|
}
|
|
402
383
|
}
|
|
403
384
|
};
|
|
404
385
|
const bundle = await rollup(inputOptions);
|
|
405
386
|
await bundle.write(outputOptions);
|
|
406
|
-
await bundle.close();
|
|
387
|
+
await bundle.close(); // Importante fechar para liberar memória
|
|
407
388
|
}
|
|
408
389
|
catch (error) {
|
|
409
390
|
Console.error('An error occurred while building with chunks:', error);
|
|
@@ -421,9 +402,10 @@ async function build(entryPoint, outfile, isProduction = false) {
|
|
|
421
402
|
const outputOptions = {
|
|
422
403
|
file: outfile,
|
|
423
404
|
format: 'iife',
|
|
424
|
-
name: '
|
|
405
|
+
name: 'Vattsjs',
|
|
425
406
|
sourcemap: !isProduction,
|
|
426
|
-
inlineDynamicImports: true
|
|
407
|
+
inlineDynamicImports: true,
|
|
408
|
+
compact: true // Ajuda na RAM
|
|
427
409
|
};
|
|
428
410
|
const bundle = await rollup(inputOptions);
|
|
429
411
|
await bundle.write(outputOptions);
|
|
@@ -438,20 +420,22 @@ async function build(entryPoint, outfile, isProduction = false) {
|
|
|
438
420
|
* Helper para lidar com notificações do Watcher
|
|
439
421
|
*/
|
|
440
422
|
function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
|
|
441
|
-
// Controla o estado do build por "geração" para evitar END atrasado
|
|
442
|
-
// (ou múltiplos ciclos) emitirem sucesso após um erro.
|
|
443
423
|
let currentBuildId = 0;
|
|
444
424
|
let lastStartedBuildId = 0;
|
|
445
425
|
const erroredBuildIds = new Set();
|
|
446
|
-
// DEBUG: stack trace rate-limited
|
|
447
|
-
let lastTraceAt = 0;
|
|
448
426
|
watcher.on('event', event => {
|
|
449
427
|
if (event.code === 'START') {
|
|
450
428
|
currentBuildId += 1;
|
|
451
429
|
lastStartedBuildId = currentBuildId;
|
|
430
|
+
// Dica pro V8 limpar lixo antes de começar um build pesado
|
|
431
|
+
if (global.gc) {
|
|
432
|
+
try {
|
|
433
|
+
global.gc();
|
|
434
|
+
}
|
|
435
|
+
catch (e) { }
|
|
436
|
+
}
|
|
452
437
|
}
|
|
453
438
|
if (event.code === 'ERROR') {
|
|
454
|
-
// Marca erro para o build atualmente em andamento.
|
|
455
439
|
erroredBuildIds.add(currentBuildId);
|
|
456
440
|
const errDetails = {
|
|
457
441
|
message: event.error?.message || 'Unknown build error',
|
|
@@ -461,7 +445,6 @@ function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
|
|
|
461
445
|
loc: event.error?.loc,
|
|
462
446
|
buildId: currentBuildId
|
|
463
447
|
};
|
|
464
|
-
// Notifica erro imediatamente
|
|
465
448
|
if (hotReloadManager) {
|
|
466
449
|
hotReloadManager.onBuildComplete(false, errDetails);
|
|
467
450
|
}
|
|
@@ -470,21 +453,18 @@ function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
|
|
|
470
453
|
if (resolveFirstBuild)
|
|
471
454
|
resolveFirstBuild();
|
|
472
455
|
}
|
|
473
|
-
if (event.code === 'BUNDLE_END')
|
|
456
|
+
if (event.code === 'BUNDLE_END') {
|
|
457
|
+
// CRÍTICO: Fechar o bundle libera a memória dos módulos
|
|
474
458
|
event.result.close();
|
|
459
|
+
}
|
|
475
460
|
if (event.code === 'END') {
|
|
476
461
|
const endBuildId = currentBuildId;
|
|
477
462
|
const hadError = erroredBuildIds.has(endBuildId);
|
|
478
|
-
// Só emite sucesso se:
|
|
479
|
-
// 1) esse END é do build mais recentemente iniciado (evita END atrasado)
|
|
480
|
-
// 2) esse build não teve ERROR
|
|
481
463
|
if (endBuildId === lastStartedBuildId && !hadError) {
|
|
482
464
|
if (hotReloadManager) {
|
|
483
465
|
hotReloadManager.onBuildComplete(true, { buildId: endBuildId });
|
|
484
466
|
}
|
|
485
467
|
}
|
|
486
|
-
// Limpa estados antigos pra não crescer sem limite.
|
|
487
|
-
// (qualquer build mais antigo que o último START não faz mais sentido manter)
|
|
488
468
|
for (const id of erroredBuildIds) {
|
|
489
469
|
if (id < lastStartedBuildId)
|
|
490
470
|
erroredBuildIds.delete(id);
|
|
@@ -502,11 +482,9 @@ function handleWatcherEvents(watcher, hotReloadManager, resolveFirstBuild) {
|
|
|
502
482
|
async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
|
|
503
483
|
await cleanDirectoryExcept(outdir, 'temp');
|
|
504
484
|
try {
|
|
505
|
-
// DEV MODE: isProduction = false
|
|
506
485
|
const inputOptions = createRollupConfig(entryPoint, outdir, false);
|
|
507
486
|
const outputOptions = {
|
|
508
487
|
dir: outdir,
|
|
509
|
-
// Em DEV usamos ESM para suportar externals como react/react-dom sem output.globals
|
|
510
488
|
format: 'es',
|
|
511
489
|
entryFileNames: 'main.js',
|
|
512
490
|
sourcemap: true
|
|
@@ -517,7 +495,9 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
|
|
|
517
495
|
watch: {
|
|
518
496
|
exclude: 'node_modules/**',
|
|
519
497
|
clearScreen: false,
|
|
520
|
-
skipWrite: false
|
|
498
|
+
skipWrite: false,
|
|
499
|
+
// Atraso curto para evitar múltiplos rebuilds rápidos que comem CPU/RAM
|
|
500
|
+
buildDelay: 100
|
|
521
501
|
}
|
|
522
502
|
};
|
|
523
503
|
const watcher = rollupWatch(watchOptions);
|
|
@@ -540,7 +520,6 @@ async function watch(entryPoint, outfile, hotReloadManager = null) {
|
|
|
540
520
|
const inputOptions = createRollupConfig(entryPoint, outdir, false);
|
|
541
521
|
const outputOptions = {
|
|
542
522
|
file: outfile,
|
|
543
|
-
// Em DEV usamos ESM para suportar externals como react/react-dom sem output.globals
|
|
544
523
|
format: 'es',
|
|
545
524
|
sourcemap: true
|
|
546
525
|
};
|
|
@@ -549,7 +528,8 @@ async function watch(entryPoint, outfile, hotReloadManager = null) {
|
|
|
549
528
|
output: outputOptions,
|
|
550
529
|
watch: {
|
|
551
530
|
exclude: 'node_modules/**',
|
|
552
|
-
clearScreen: false
|
|
531
|
+
clearScreen: false,
|
|
532
|
+
buildDelay: 100
|
|
553
533
|
}
|
|
554
534
|
};
|
|
555
535
|
const watcher = rollupWatch(watchOptions);
|
|
@@ -569,14 +549,21 @@ async function cleanDirectoryExcept(dirPath, excludeFolder) {
|
|
|
569
549
|
return;
|
|
570
550
|
const excludes = Array.isArray(excludeFolder) ? excludeFolder : [excludeFolder];
|
|
571
551
|
const items = await readdir(dirPath);
|
|
572
|
-
//
|
|
573
|
-
|
|
552
|
+
// OTIMIZAÇÃO: Loop sequencial ao invés de Promise.all.
|
|
553
|
+
// Promise.all é mais rápido, mas cria dezenas/centenas de Promises simultâneas na RAM.
|
|
554
|
+
// O loop sequencial é mais gentil com o Garbage Collector.
|
|
555
|
+
for (const item of items) {
|
|
574
556
|
if (excludes.includes(item))
|
|
575
|
-
|
|
557
|
+
continue;
|
|
576
558
|
const itemPath = path.join(dirPath, item);
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
559
|
+
try {
|
|
560
|
+
const info = await stat(itemPath);
|
|
561
|
+
await rm(itemPath, { recursive: info.isDirectory(), force: true });
|
|
562
|
+
}
|
|
563
|
+
catch (e) {
|
|
564
|
+
// Ignora erro se arquivo sumir durante o loop
|
|
565
|
+
}
|
|
566
|
+
}
|
|
580
567
|
}
|
|
581
568
|
catch (e) {
|
|
582
569
|
Console.warn(`Warning cleaning directory: ${e.message}`);
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
* See the License for the specific language governing permissions and
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
|
-
// Sistema de roteamento do lado do cliente para hweb-sdk
|
|
19
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
19
|
exports.router = void 0;
|
|
21
20
|
class Router {
|
|
@@ -201,7 +201,7 @@ function App({ componentMap, routes, initialComponentPath, initialParams, layout
|
|
|
201
201
|
// para garantir que o ErrorModal apareça em qualquer estado.
|
|
202
202
|
let resolvedContent;
|
|
203
203
|
if (!CurrentPageComponent || initialComponentPath === '__404__') {
|
|
204
|
-
const NotFoundComponent = window.
|
|
204
|
+
const NotFoundComponent = window.__VATTS_NOT_FOUND__;
|
|
205
205
|
if (NotFoundComponent) {
|
|
206
206
|
const NotFoundContent = (0, jsx_runtime_1.jsx)(NotFoundComponent, {});
|
|
207
207
|
resolvedContent = layoutComponent
|
|
@@ -209,7 +209,7 @@ function App({ componentMap, routes, initialComponentPath, initialParams, layout
|
|
|
209
209
|
: NotFoundContent;
|
|
210
210
|
}
|
|
211
211
|
else {
|
|
212
|
-
const DefaultNotFound = window.
|
|
212
|
+
const DefaultNotFound = window.__VATTS_DEFAULT_NOT_FOUND__;
|
|
213
213
|
const NotFoundContent = (0, jsx_runtime_1.jsx)(DefaultNotFound, {});
|
|
214
214
|
resolvedContent = layoutComponent
|
|
215
215
|
? react_1.default.createElement(layoutComponent, { children: NotFoundContent })
|
|
@@ -261,11 +261,11 @@ function initializeClient() {
|
|
|
261
261
|
// Cria o mapa de componentes dinamicamente a partir dos módulos carregados
|
|
262
262
|
const componentMap = {};
|
|
263
263
|
// Registra todos os componentes que foram importados
|
|
264
|
-
if (window.
|
|
265
|
-
Object.assign(componentMap, window.
|
|
264
|
+
if (window.__VATTS_COMPONENTS__) {
|
|
265
|
+
Object.assign(componentMap, window.__VATTS_COMPONENTS__);
|
|
266
266
|
}
|
|
267
267
|
else {
|
|
268
|
-
console.warn('[Vatts] No components found in window.
|
|
268
|
+
console.warn('[Vatts] No components found in window.__VATTS_COMPONENTS__');
|
|
269
269
|
}
|
|
270
270
|
const container = document.getElementById('root');
|
|
271
271
|
if (!container) {
|
|
@@ -292,7 +292,7 @@ function initializeClient() {
|
|
|
292
292
|
const root = (0, client_1.createRoot)(container);
|
|
293
293
|
// Salva a referência globalmente
|
|
294
294
|
window.__VATTS_ROOT__ = root;
|
|
295
|
-
root.render((0, jsx_runtime_1.jsx)(App, { componentMap: componentMap, routes: initialData.routes, initialComponentPath: initialData.initialComponentPath, initialParams: initialData.initialParams, layoutComponent: window.
|
|
295
|
+
root.render((0, jsx_runtime_1.jsx)(App, { componentMap: componentMap, routes: initialData.routes, initialComponentPath: initialData.initialComponentPath, initialParams: initialData.initialParams, layoutComponent: window.__VATTS_LAYOUT__ }));
|
|
296
296
|
}
|
|
297
297
|
catch (error) {
|
|
298
298
|
console.error('[Watts] Critical Error rendering application:', error);
|
|
@@ -316,7 +316,7 @@ if (document.readyState === 'loading') {
|
|
|
316
316
|
else {
|
|
317
317
|
// ESM Hoisting Fix:
|
|
318
318
|
// Como este arquivo é importado pelo arquivo gerado automaticamente, ele executa
|
|
319
|
-
// ANTES do corpo do arquivo gerado (onde window.
|
|
319
|
+
// ANTES do corpo do arquivo gerado (onde window.__VATTS_COMPONENTS__ é definido).
|
|
320
320
|
// Usamos setTimeout para garantir que a inicialização ocorra após as atribuições globais.
|
|
321
321
|
setTimeout(initializeClient, 0);
|
|
322
322
|
}
|
package/dist/env/env.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadEnv = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const console_1 = __importDefault(require("../api/console"));
|
|
10
|
+
function parse(src) {
|
|
11
|
+
const obj = {};
|
|
12
|
+
const lines = src.toString().split('\n');
|
|
13
|
+
for (const line of lines) {
|
|
14
|
+
const trimmedLine = line.trim();
|
|
15
|
+
if (trimmedLine.startsWith('#') || trimmedLine === '') {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const match = trimmedLine.match(/^([^=]+)=(.*)$/);
|
|
19
|
+
if (match) {
|
|
20
|
+
const key = match[1].trim();
|
|
21
|
+
let value = match[2].trim();
|
|
22
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
23
|
+
value = value.substring(1, value.length - 1);
|
|
24
|
+
}
|
|
25
|
+
obj[key] = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return obj;
|
|
29
|
+
}
|
|
30
|
+
function applyEnv(filePath) {
|
|
31
|
+
if (!fs_1.default.existsSync(filePath))
|
|
32
|
+
return;
|
|
33
|
+
try {
|
|
34
|
+
const fileContent = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
35
|
+
const parsed = parse(fileContent);
|
|
36
|
+
for (const key in parsed) {
|
|
37
|
+
if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
|
|
38
|
+
process.env[key] = parsed[key];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
console_1.default.error(`Error loading env file ${filePath}:`, e);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const loadEnv = (options) => {
|
|
47
|
+
const { dir, dev, envFiles = [] } = options;
|
|
48
|
+
const filesToLoad = [".env", ...envFiles].map((file) => path_1.default.join(dir, file));
|
|
49
|
+
filesToLoad.forEach(applyEnv);
|
|
50
|
+
if (dev) {
|
|
51
|
+
for (const file of filesToLoad) {
|
|
52
|
+
if (fs_1.default.existsSync(file)) {
|
|
53
|
+
let watchTimeout;
|
|
54
|
+
fs_1.default.watch(file, (eventType) => {
|
|
55
|
+
if (eventType === 'change') {
|
|
56
|
+
// Limpa o timeout anterior para evitar execuções múltiplas
|
|
57
|
+
clearTimeout(watchTimeout);
|
|
58
|
+
// Define um novo timeout de 100ms
|
|
59
|
+
watchTimeout = setTimeout(() => {
|
|
60
|
+
console_1.default.info(`Reloading environment variables from ${path_1.default.basename(file)}.`);
|
|
61
|
+
applyEnv(file);
|
|
62
|
+
}, 100);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
exports.loadEnv = loadEnv;
|
package/dist/helpers.js
CHANGED
|
@@ -132,6 +132,7 @@ async function loadVattsConfig(projectDir, phase) {
|
|
|
132
132
|
individualRequestTimeout: 30000,
|
|
133
133
|
maxUrlLength: 2048,
|
|
134
134
|
accessLogging: true,
|
|
135
|
+
envFiles: [],
|
|
135
136
|
};
|
|
136
137
|
try {
|
|
137
138
|
// Tenta primeiro .ts, depois .js
|
|
@@ -315,13 +316,15 @@ const parseBody = (req) => {
|
|
|
315
316
|
/**
|
|
316
317
|
* Inicializa servidor nativo do Vatts.js usando HTTP ou HTTPS
|
|
317
318
|
*/
|
|
318
|
-
async function initNativeServer(
|
|
319
|
+
async function initNativeServer(vattsApp, options, port, hostname) {
|
|
319
320
|
const time = Date.now();
|
|
320
|
-
await hwebApp.prepare();
|
|
321
321
|
const projectDir = options.dir || process.cwd();
|
|
322
322
|
const phase = options.dev ? 'development' : 'production';
|
|
323
323
|
const vattsConfig = await loadVattsConfig(projectDir, phase);
|
|
324
|
-
|
|
324
|
+
// Passa envFiles da config para as opções do vatts
|
|
325
|
+
options.envFiles = vattsConfig.envFiles;
|
|
326
|
+
await vattsApp.prepare();
|
|
327
|
+
const handler = vattsApp.getRequestHandler();
|
|
325
328
|
const msg = console_1.default.dynamicLine(`${console_1.Colors.Bright}Starting Vatts.js on port ${options.port}${console_1.Colors.Reset}`);
|
|
326
329
|
// --- LÓGICA DO LISTENER (REUTILIZÁVEL) ---
|
|
327
330
|
// Extraímos a lógica principal para uma variável
|
|
@@ -461,7 +464,7 @@ async function initNativeServer(hwebApp, options, port, hostname) {
|
|
|
461
464
|
ca: options.ssl.ca ? fs_1.default.readFileSync(options.ssl.ca) : undefined
|
|
462
465
|
};
|
|
463
466
|
// 1. Cria o servidor HTTPS principal
|
|
464
|
-
server = https_1.default.createServer(sslOptions, requestListener);
|
|
467
|
+
server = https_1.default.createServer(sslOptions, requestListener);
|
|
465
468
|
// 2. Cria o servidor de REDIRECIONAMENTO (HTTP -> HTTPS)
|
|
466
469
|
const httpRedirectPort = options.ssl.redirectPort;
|
|
467
470
|
http_1.default.createServer((req, res) => {
|
|
@@ -490,7 +493,7 @@ async function initNativeServer(hwebApp, options, port, hostname) {
|
|
|
490
493
|
else {
|
|
491
494
|
// --- MODO HTTP (Original) ---
|
|
492
495
|
// Cria o servidor HTTP nativo
|
|
493
|
-
server = http_1.default.createServer(requestListener);
|
|
496
|
+
server = http_1.default.createServer(requestListener);
|
|
494
497
|
}
|
|
495
498
|
// Configurações de segurança do servidor (usa configuração personalizada)
|
|
496
499
|
server.setTimeout(vattsConfig.serverTimeout || 35000); // Timeout geral do servidor
|
|
@@ -502,26 +505,26 @@ async function initNativeServer(hwebApp, options, port, hostname) {
|
|
|
502
505
|
msg.end(`${console_1.Colors.Bright}Ready on port ${console_1.Colors.BgGreen} ${options.port} ${console_1.Colors.Reset}${console_1.Colors.Bright} in ${Date.now() - time}ms${console_1.Colors.Reset}\n`);
|
|
503
506
|
});
|
|
504
507
|
// Configura WebSocket para hot reload (Comum a ambos)
|
|
505
|
-
|
|
506
|
-
|
|
508
|
+
vattsApp.setupWebSocket(server);
|
|
509
|
+
vattsApp.executeInstrumentation();
|
|
507
510
|
return server;
|
|
508
511
|
}
|
|
509
512
|
// --- Função Principal ---
|
|
510
513
|
function app(options = {}) {
|
|
511
514
|
const framework = options.framework || 'native';
|
|
512
515
|
index_1.FrameworkAdapterFactory.setFramework(framework);
|
|
513
|
-
// Tipando a app principal do
|
|
514
|
-
const
|
|
516
|
+
// Tipando a app principal do vatts
|
|
517
|
+
const vattsApp = (0, index_1.default)(options);
|
|
515
518
|
return {
|
|
516
|
-
...
|
|
519
|
+
...vattsApp,
|
|
517
520
|
/**
|
|
518
521
|
* Integra com uma aplicação de qualquer framework (Express, Fastify, etc)
|
|
519
522
|
* O 'serverApp: any' é mantido para flexibilidade, já que pode ser de tipos diferentes.
|
|
520
523
|
*/
|
|
521
524
|
integrate: async (serverApp) => {
|
|
522
|
-
await
|
|
523
|
-
const handler =
|
|
524
|
-
// O framework é setado nas opções do
|
|
525
|
+
await vattsApp.prepare();
|
|
526
|
+
const handler = vattsApp.getRequestHandler();
|
|
527
|
+
// O framework é setado nas opções do vatts, que deve
|
|
525
528
|
// retornar o handler correto em getRequestHandler()
|
|
526
529
|
// A lógica de integração original parece correta.
|
|
527
530
|
if (framework === 'express') {
|
|
@@ -536,7 +539,7 @@ function app(options = {}) {
|
|
|
536
539
|
serverApp.use(express.json());
|
|
537
540
|
serverApp.use(express.urlencoded({ extended: true }));
|
|
538
541
|
serverApp.use(handler);
|
|
539
|
-
|
|
542
|
+
vattsApp.setupWebSocket(serverApp);
|
|
540
543
|
}
|
|
541
544
|
else if (framework === 'fastify') {
|
|
542
545
|
try {
|
|
@@ -554,14 +557,14 @@ function app(options = {}) {
|
|
|
554
557
|
await serverApp.register(async (fastify) => {
|
|
555
558
|
fastify.all('*', handler);
|
|
556
559
|
});
|
|
557
|
-
|
|
560
|
+
vattsApp.setupWebSocket(serverApp);
|
|
558
561
|
}
|
|
559
562
|
else {
|
|
560
563
|
// Generic integration (assume Express-like)
|
|
561
564
|
serverApp.use(handler);
|
|
562
|
-
|
|
565
|
+
vattsApp.setupWebSocket(serverApp);
|
|
563
566
|
}
|
|
564
|
-
|
|
567
|
+
vattsApp.executeInstrumentation();
|
|
565
568
|
return serverApp;
|
|
566
569
|
},
|
|
567
570
|
/**
|
|
@@ -602,7 +605,7 @@ ${console_1.Colors.Bright + console_1.Colors.FgRed} \\/ /~~\\ | | .__/
|
|
|
602
605
|
if (framework !== 'native') {
|
|
603
606
|
console_1.default.warn(`The "${framework}" framework was selected, but the init() method only works with the "native" framework. Starting native server...`);
|
|
604
607
|
}
|
|
605
|
-
return await initNativeServer(
|
|
608
|
+
return await initNativeServer(vattsApp, options, actualPort, actualHostname);
|
|
606
609
|
}
|
|
607
610
|
};
|
|
608
611
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type { GenericRequest, GenericResponse, CookieOptions } from './types/fra
|
|
|
9
9
|
export { app } from './helpers';
|
|
10
10
|
export type { WebSocketContext, WebSocketHandler } from './types';
|
|
11
11
|
export type { VattsConfig, VattsConfigFunction } from './types';
|
|
12
|
-
export default function
|
|
12
|
+
export default function vatts(options: VattsOptions): {
|
|
13
13
|
prepare: () => Promise<void>;
|
|
14
14
|
executeInstrumentation: () => void;
|
|
15
15
|
getRequestHandler: () => RequestHandler;
|
package/dist/index.js
CHANGED
|
@@ -53,7 +53,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
53
53
|
};
|
|
54
54
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
55
|
exports.app = exports.FrameworkAdapterFactory = exports.FastifyAdapter = exports.ExpressAdapter = exports.VattsResponse = exports.VattsRequest = void 0;
|
|
56
|
-
exports.default =
|
|
56
|
+
exports.default = vatts;
|
|
57
57
|
const path_1 = __importDefault(require("path"));
|
|
58
58
|
const fs_1 = __importDefault(require("fs"));
|
|
59
59
|
const express_1 = require("./adapters/express");
|
|
@@ -66,6 +66,7 @@ Object.defineProperty(exports, "VattsResponse", { enumerable: true, get: functio
|
|
|
66
66
|
const hotReload_1 = require("./hotReload");
|
|
67
67
|
const factory_1 = require("./adapters/factory");
|
|
68
68
|
const console_1 = __importStar(require("./api/console"));
|
|
69
|
+
const env_1 = require("./env/env");
|
|
69
70
|
// RPC
|
|
70
71
|
const server_1 = require("./rpc/server");
|
|
71
72
|
const types_1 = require("./rpc/types");
|
|
@@ -161,12 +162,12 @@ function createEntryFile(projectDir, routes) {
|
|
|
161
162
|
.join('\n');
|
|
162
163
|
// Registra o layout se existir
|
|
163
164
|
const layoutRegistration = layout
|
|
164
|
-
? `window.
|
|
165
|
-
: `window.
|
|
165
|
+
? `window.__VATTS_LAYOUT__ = LayoutComponent.default || LayoutComponent;`
|
|
166
|
+
: `window.__VATTS_LAYOUT__ = null;`;
|
|
166
167
|
// Registra o notFound se existir
|
|
167
168
|
const notFoundRegistration = notFound
|
|
168
|
-
? `window.
|
|
169
|
-
: `window.
|
|
169
|
+
? `window.__VATTS_NOT_FOUND__ = NotFoundComponent.default || NotFoundComponent;`
|
|
170
|
+
: `window.__VATTS_NOT_FOUND__ = null;`;
|
|
170
171
|
// Caminho correto para o entry.client
|
|
171
172
|
// IMPORTANT: quando o pacote é instalado via npm, bundlers (Rollup/Vite/etc.) não transpilam TSX em node_modules.
|
|
172
173
|
// Por isso, aqui a gente sempre aponta para os artefatos compilados em dist/.
|
|
@@ -176,14 +177,14 @@ function createEntryFile(projectDir, routes) {
|
|
|
176
177
|
// Import do DefaultNotFound do SDK (compilado)
|
|
177
178
|
const defaultNotFoundPath = path_1.default.join(sdkDir, 'dist', 'client', 'DefaultNotFound.js');
|
|
178
179
|
const relativeDefaultNotFoundPath = path_1.default.relative(tempDir, defaultNotFoundPath).replace(/\\/g, '/');
|
|
179
|
-
const entryContent = `// Arquivo gerado automaticamente pelo
|
|
180
|
+
const entryContent = `// Arquivo gerado automaticamente pelo vatts
|
|
180
181
|
${imports}
|
|
181
182
|
${layoutImport}
|
|
182
183
|
${notFoundImport}
|
|
183
184
|
import DefaultNotFound from '${relativeDefaultNotFoundPath}';
|
|
184
185
|
|
|
185
186
|
// Registra os componentes para o cliente
|
|
186
|
-
window.
|
|
187
|
+
window.__VATTS_COMPONENTS__ = {
|
|
187
188
|
${componentRegistration}
|
|
188
189
|
};
|
|
189
190
|
|
|
@@ -193,8 +194,8 @@ ${layoutRegistration}
|
|
|
193
194
|
// Registra o notFound se existir
|
|
194
195
|
${notFoundRegistration}
|
|
195
196
|
|
|
196
|
-
|
|
197
|
-
window.
|
|
197
|
+
|
|
198
|
+
window.__VATTS_DEFAULT_NOT_FOUND__ = DefaultNotFound;
|
|
198
199
|
|
|
199
200
|
// Importa e executa o entry.client.tsx
|
|
200
201
|
import '${relativeEntryPath}';
|
|
@@ -212,8 +213,9 @@ import '${relativeEntryPath}';
|
|
|
212
213
|
throw e;
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
|
-
function
|
|
216
|
-
const { dev = true, dir = process.cwd(), port = 3000 } = options;
|
|
216
|
+
function vatts(options) {
|
|
217
|
+
const { dev = true, dir = process.cwd(), port = 3000, envFiles } = options;
|
|
218
|
+
(0, env_1.loadEnv)({ dir, dev, envFiles });
|
|
217
219
|
// @ts-ignore
|
|
218
220
|
process.vatts = options;
|
|
219
221
|
const userWebDir = path_1.default.join(dir, 'src', 'web');
|
package/dist/renderer.js
CHANGED
|
@@ -175,7 +175,7 @@ async function render({ req, route, params, allRoutes }) {
|
|
|
175
175
|
<html lang="${htmlLang}">
|
|
176
176
|
<head>
|
|
177
177
|
${metaTags}
|
|
178
|
-
<title>${metadata.title || '
|
|
178
|
+
<title>${metadata.title || 'Vatts.js'}</title>
|
|
179
179
|
</head>
|
|
180
180
|
<body>
|
|
181
181
|
<div id="root"></div>
|
package/dist/types.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface VattsOptions {
|
|
|
26
26
|
cert: string;
|
|
27
27
|
ca?: string;
|
|
28
28
|
};
|
|
29
|
+
envFiles?: string[];
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* Interface para as configurações avançadas do servidor Vatts.js.
|
|
@@ -137,6 +138,10 @@ export interface VattsConfig {
|
|
|
137
138
|
* Exemplo: { 'X-Custom-Header': 'value', 'X-Powered-By': 'Vatts.js' }
|
|
138
139
|
*/
|
|
139
140
|
customHeaders?: Record<string, string>;
|
|
141
|
+
/**
|
|
142
|
+
* Arquivos .env adicionais para carregar. O .env padrão é sempre carregado.
|
|
143
|
+
*/
|
|
144
|
+
envFiles?: string[];
|
|
140
145
|
}
|
|
141
146
|
/**
|
|
142
147
|
* Tipo da função de configuração que pode ser exportada no vatts.config.js
|
|
@@ -192,12 +197,10 @@ export type RequestHandler = (req: any, res: any) => Promise<void>;
|
|
|
192
197
|
/**
|
|
193
198
|
* Define o formato de uma função que manipula uma rota da API.
|
|
194
199
|
*/
|
|
195
|
-
export type BackendHandler = (request: VattsRequest,
|
|
196
|
-
params: {
|
|
200
|
+
export type BackendHandler = (request: VattsRequest, params: {
|
|
197
201
|
[key: string]: string;
|
|
198
202
|
}) => Promise<VattsResponse> | VattsResponse;
|
|
199
|
-
export type VattsMiddleware = (request: VattsRequest,
|
|
200
|
-
params: {
|
|
203
|
+
export type VattsMiddleware = (request: VattsRequest, params: {
|
|
201
204
|
[key: string]: string;
|
|
202
205
|
}, next: () => Promise<VattsResponse>) => Promise<VattsResponse> | VattsResponse;
|
|
203
206
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vatts",
|
|
3
|
-
"version": "1.0.2-alpha.
|
|
3
|
+
"version": "1.0.2-alpha.3",
|
|
4
4
|
"description": "Vatts.js is a high-level framework for building web applications with ease and speed. It provides a robust set of tools and features to streamline development and enhance productivity.",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"author": "itsmuzin",
|