vatts 1.0.2-alpha.3 → 1.0.2-alpha.4
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/vatts.js +91 -100
- package/dist/builder.js +2 -1
- package/dist/client/clientRouter.d.ts +11 -54
- package/dist/client/clientRouter.js +39 -94
- package/dist/client/rpc.d.ts +1 -1
- package/dist/client/rpc.js +19 -2
- package/dist/index.js +41 -85
- package/dist/renderer.d.ts +3 -1
- package/dist/renderer.js +151 -170
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -59,7 +59,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
59
59
|
const express_1 = require("./adapters/express");
|
|
60
60
|
const builder_1 = require("./builder");
|
|
61
61
|
const router_1 = require("./router");
|
|
62
|
-
const renderer_1 = require("./renderer");
|
|
62
|
+
const renderer_1 = require("./renderer"); // Usando a nova função de streaming
|
|
63
63
|
const http_1 = require("./api/http");
|
|
64
64
|
Object.defineProperty(exports, "VattsRequest", { enumerable: true, get: function () { return http_1.VattsRequest; } });
|
|
65
65
|
Object.defineProperty(exports, "VattsResponse", { enumerable: true, get: function () { return http_1.VattsResponse; } });
|
|
@@ -121,13 +121,9 @@ function isLargeProject(projectDir) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
scanDirectory(srcDir);
|
|
124
|
-
// Considera projeto grande se:
|
|
125
|
-
// - Mais de 20 arquivos de frontend/style
|
|
126
|
-
// - Ou tamanho total > 500KB
|
|
127
124
|
return totalFiles > 20 || totalSize > 500 * 1024;
|
|
128
125
|
}
|
|
129
126
|
catch (error) {
|
|
130
|
-
// Em caso de erro, assume que não é um projeto grande
|
|
131
127
|
return false;
|
|
132
128
|
}
|
|
133
129
|
}
|
|
@@ -137,44 +133,32 @@ function createEntryFile(projectDir, routes) {
|
|
|
137
133
|
const tempDir = path_1.default.join(projectDir, '.vatts', 'temp');
|
|
138
134
|
fs_1.default.mkdirSync(tempDir, { recursive: true });
|
|
139
135
|
const entryFilePath = path_1.default.join(tempDir, 'entry.client.js');
|
|
140
|
-
// Verifica se há layout
|
|
141
136
|
const layout = (0, router_1.getLayout)();
|
|
142
|
-
// Verifica se há notFound personalizado
|
|
143
137
|
const notFound = (0, router_1.getNotFound)();
|
|
144
|
-
// Gera imports dinâmicos para cada componente
|
|
145
138
|
const imports = routes
|
|
146
139
|
.map((route, index) => {
|
|
147
140
|
const relativePath = path_1.default.relative(tempDir, route.componentPath).replace(/\\/g, '/');
|
|
148
141
|
return `import route${index} from '${relativePath}';`;
|
|
149
142
|
})
|
|
150
143
|
.join('\n');
|
|
151
|
-
// Import do layout se existir
|
|
152
144
|
const layoutImport = layout
|
|
153
145
|
? `import LayoutComponent from '${path_1.default.relative(tempDir, layout.componentPath).replace(/\\/g, '/')}';`
|
|
154
146
|
: '';
|
|
155
|
-
// Import do notFound se existir
|
|
156
147
|
const notFoundImport = notFound
|
|
157
148
|
? `import NotFoundComponent from '${path_1.default.relative(tempDir, notFound.componentPath).replace(/\\/g, '/')}';`
|
|
158
149
|
: '';
|
|
159
|
-
// Registra os componentes no window para o cliente acessar
|
|
160
150
|
const componentRegistration = routes
|
|
161
151
|
.map((route, index) => ` '${route.componentPath}': route${index}.component || route${index}.default?.component,`)
|
|
162
152
|
.join('\n');
|
|
163
|
-
// Registra o layout se existir
|
|
164
153
|
const layoutRegistration = layout
|
|
165
154
|
? `window.__VATTS_LAYOUT__ = LayoutComponent.default || LayoutComponent;`
|
|
166
155
|
: `window.__VATTS_LAYOUT__ = null;`;
|
|
167
|
-
// Registra o notFound se existir
|
|
168
156
|
const notFoundRegistration = notFound
|
|
169
157
|
? `window.__VATTS_NOT_FOUND__ = NotFoundComponent.default || NotFoundComponent;`
|
|
170
158
|
: `window.__VATTS_NOT_FOUND__ = null;`;
|
|
171
|
-
|
|
172
|
-
// IMPORTANT: quando o pacote é instalado via npm, bundlers (Rollup/Vite/etc.) não transpilam TSX em node_modules.
|
|
173
|
-
// Por isso, aqui a gente sempre aponta para os artefatos compilados em dist/.
|
|
174
|
-
const sdkDir = path_1.default.dirname(__dirname); // pasta do pacote (pai de dist/ e src/)
|
|
159
|
+
const sdkDir = path_1.default.dirname(__dirname);
|
|
175
160
|
const entryClientPath = path_1.default.join(sdkDir, 'dist', 'client', 'entry.client.js');
|
|
176
161
|
const relativeEntryPath = path_1.default.relative(tempDir, entryClientPath).replace(/\\/g, '/');
|
|
177
|
-
// Import do DefaultNotFound do SDK (compilado)
|
|
178
162
|
const defaultNotFoundPath = path_1.default.join(sdkDir, 'dist', 'client', 'DefaultNotFound.js');
|
|
179
163
|
const relativeDefaultNotFoundPath = path_1.default.relative(tempDir, defaultNotFoundPath).replace(/\\/g, '/');
|
|
180
164
|
const entryContent = `// Arquivo gerado automaticamente pelo vatts
|
|
@@ -183,28 +167,22 @@ ${layoutImport}
|
|
|
183
167
|
${notFoundImport}
|
|
184
168
|
import DefaultNotFound from '${relativeDefaultNotFoundPath}';
|
|
185
169
|
|
|
186
|
-
// Registra os componentes para o cliente
|
|
187
170
|
window.__VATTS_COMPONENTS__ = {
|
|
188
171
|
${componentRegistration}
|
|
189
172
|
};
|
|
190
173
|
|
|
191
|
-
// Registra o layout se existir
|
|
192
174
|
${layoutRegistration}
|
|
193
|
-
|
|
194
|
-
// Registra o notFound se existir
|
|
195
175
|
${notFoundRegistration}
|
|
196
176
|
|
|
197
|
-
|
|
198
177
|
window.__VATTS_DEFAULT_NOT_FOUND__ = DefaultNotFound;
|
|
199
178
|
|
|
200
|
-
// Importa e executa o entry.client.tsx
|
|
201
179
|
import '${relativeEntryPath}';
|
|
202
180
|
`;
|
|
203
181
|
try {
|
|
204
182
|
fs_1.default.writeFileSync(entryFilePath, entryContent);
|
|
205
183
|
}
|
|
206
184
|
catch (e) {
|
|
207
|
-
console.error("
|
|
185
|
+
console.error("Error writing entry file", e);
|
|
208
186
|
}
|
|
209
187
|
return entryFilePath;
|
|
210
188
|
}
|
|
@@ -218,74 +196,54 @@ function vatts(options) {
|
|
|
218
196
|
(0, env_1.loadEnv)({ dir, dev, envFiles });
|
|
219
197
|
// @ts-ignore
|
|
220
198
|
process.vatts = options;
|
|
199
|
+
// @ts-ignore
|
|
200
|
+
process.env.PORT = options.port;
|
|
221
201
|
const userWebDir = path_1.default.join(dir, 'src', 'web');
|
|
222
202
|
const userWebRoutesDir = path_1.default.join(userWebDir, 'routes');
|
|
223
203
|
const userBackendRoutesDir = path_1.default.join(dir, 'src', 'backend', 'routes');
|
|
224
|
-
/**
|
|
225
|
-
* Executa middlewares sequencialmente e depois o handler final
|
|
226
|
-
* @param middlewares Array de middlewares para executar
|
|
227
|
-
* @param finalHandler Handler final da rota
|
|
228
|
-
* @param request Requisição do Vatts.js
|
|
229
|
-
* @param params Parâmetros da rota
|
|
230
|
-
* @returns Resposta do middleware ou handler final
|
|
231
|
-
*/
|
|
232
204
|
async function executeMiddlewareChain(middlewares, finalHandler, request, params) {
|
|
233
205
|
if (!middlewares || middlewares.length === 0) {
|
|
234
|
-
// Não há middlewares, executa diretamente o handler final
|
|
235
206
|
return await finalHandler(request, params);
|
|
236
207
|
}
|
|
237
208
|
let currentIndex = 0;
|
|
238
|
-
// Função next que será chamada pelos middlewares
|
|
239
209
|
const next = async () => {
|
|
240
210
|
if (currentIndex < middlewares.length) {
|
|
241
|
-
// Ainda há middlewares para executar
|
|
242
211
|
const currentMiddleware = middlewares[currentIndex];
|
|
243
212
|
currentIndex++;
|
|
244
213
|
return await currentMiddleware(request, params, next);
|
|
245
214
|
}
|
|
246
215
|
else {
|
|
247
|
-
// Todos os middlewares foram executados, chama o handler final
|
|
248
216
|
return await finalHandler(request, params);
|
|
249
217
|
}
|
|
250
218
|
};
|
|
251
|
-
// Inicia a cadeia de execução
|
|
252
219
|
return await next();
|
|
253
220
|
}
|
|
254
221
|
let frontendRoutes = [];
|
|
255
222
|
let hotReloadManager = null;
|
|
256
223
|
let entryPoint;
|
|
257
|
-
let outfile;
|
|
258
|
-
// Função para regenerar o entry file
|
|
259
224
|
const regenerateEntryFile = () => {
|
|
260
|
-
// Recarrega todas as rotas e componentes
|
|
261
225
|
const newFrontendRoutes = (0, router_1.loadRoutes)(userWebRoutesDir);
|
|
262
226
|
const newLayout = (0, router_1.loadLayout)(userWebDir);
|
|
263
227
|
const newNotFound = (0, router_1.loadNotFound)(userWebDir);
|
|
264
|
-
// Se nada mudou, não reescreve o entry file (evita disparar rebuild extra)
|
|
265
228
|
const oldKey = frontendRoutes.map(r => `${r.pattern ?? ''}:${r.componentPath}`).join('|');
|
|
266
229
|
const newKey = newFrontendRoutes.map(r => `${r.pattern ?? ''}:${r.componentPath}`).join('|');
|
|
267
230
|
if (oldKey === newKey) {
|
|
268
|
-
// Ainda atualiza refs internas de layout/notFound, mas evita re-gerar o entry.
|
|
269
231
|
frontendRoutes = newFrontendRoutes;
|
|
270
232
|
return;
|
|
271
233
|
}
|
|
272
234
|
frontendRoutes = newFrontendRoutes;
|
|
273
|
-
// Regenera o entry file
|
|
274
235
|
entryPoint = createEntryFile(dir, frontendRoutes);
|
|
275
236
|
};
|
|
276
237
|
return {
|
|
277
238
|
prepare: async () => {
|
|
278
239
|
const isProduction = !dev;
|
|
279
240
|
if (!isProduction) {
|
|
280
|
-
// Inicia hot reload apenas em desenvolvimento (com suporte ao main)
|
|
281
241
|
hotReloadManager = new hotReload_1.HotReloadManager(dir);
|
|
282
242
|
await hotReloadManager.start();
|
|
283
|
-
// Adiciona callback para recarregar TUDO quando qualquer arquivo mudar
|
|
284
243
|
hotReloadManager.onBackendApiChange(() => {
|
|
285
244
|
(0, router_1.loadBackendRoutes)(userBackendRoutesDir);
|
|
286
|
-
(0, router_1.processWebSocketRoutes)();
|
|
245
|
+
(0, router_1.processWebSocketRoutes)();
|
|
287
246
|
});
|
|
288
|
-
// Adiciona callback para regenerar entry file quando frontend mudar
|
|
289
247
|
hotReloadManager.onFrontendChange(() => {
|
|
290
248
|
regenerateEntryFile();
|
|
291
249
|
});
|
|
@@ -297,13 +255,10 @@ function vatts(options) {
|
|
|
297
255
|
const spinner1 = setInterval(() => {
|
|
298
256
|
timee.update(` ${console_1.Colors.FgYellow}${spinnerFrames1[frameIndex1]}${console_1.Colors.Reset} Loading routes and components...`);
|
|
299
257
|
frameIndex1 = (frameIndex1 + 1) % spinnerFrames1.length;
|
|
300
|
-
}, 100);
|
|
301
|
-
// ORDEM IMPORTANTE: Carrega TUDO antes de criar o arquivo de entrada
|
|
258
|
+
}, 100);
|
|
302
259
|
frontendRoutes = (0, router_1.loadRoutes)(userWebRoutesDir);
|
|
303
260
|
(0, router_1.loadBackendRoutes)(userBackendRoutesDir);
|
|
304
|
-
// Processa rotas WebSocket após carregar backend
|
|
305
261
|
(0, router_1.processWebSocketRoutes)();
|
|
306
|
-
// Carrega layout.tsx ANTES de criar o entry file
|
|
307
262
|
const layout = (0, router_1.loadLayout)(userWebDir);
|
|
308
263
|
const notFound = (0, router_1.loadNotFound)(userWebDir);
|
|
309
264
|
const outDir = path_1.default.join(dir, '.vatts');
|
|
@@ -313,20 +268,18 @@ function vatts(options) {
|
|
|
313
268
|
timee.end(`Routes and components loaded in ${Date.now() - now}ms`);
|
|
314
269
|
if (isProduction) {
|
|
315
270
|
const time = console_1.default.dynamicLine(`Starting client build`);
|
|
316
|
-
// Spinner
|
|
317
271
|
const spinnerFrames = ['|', '/', '-', '\\'];
|
|
318
272
|
let frameIndex = 0;
|
|
319
273
|
const spinner = setInterval(() => {
|
|
320
274
|
time.update(` ${console_1.Colors.FgYellow}${spinnerFrames[frameIndex]}${console_1.Colors.Reset} Building...`);
|
|
321
275
|
frameIndex = (frameIndex + 1) % spinnerFrames.length;
|
|
322
|
-
}, 100);
|
|
276
|
+
}, 100);
|
|
323
277
|
const now = Date.now();
|
|
324
278
|
await (0, builder_1.buildWithChunks)(entryPoint, outDir, isProduction);
|
|
325
279
|
const elapsed = Date.now() - now;
|
|
326
|
-
clearInterval(spinner);
|
|
327
|
-
time.update("");
|
|
280
|
+
clearInterval(spinner);
|
|
281
|
+
time.update("");
|
|
328
282
|
time.end(`Client build completed in ${elapsed}ms`);
|
|
329
|
-
// Notifica o hot reload manager que o build foi concluído
|
|
330
283
|
if (hotReloadManager) {
|
|
331
284
|
hotReloadManager.onBuildComplete(true);
|
|
332
285
|
}
|
|
@@ -341,13 +294,10 @@ function vatts(options) {
|
|
|
341
294
|
}
|
|
342
295
|
},
|
|
343
296
|
executeInstrumentation: () => {
|
|
344
|
-
// verificar se dir/src/instrumentation.(tsx/jsx/js/ts) existe com regex
|
|
345
297
|
const instrumentationFile = fs_1.default.readdirSync(path_1.default.join(dir, 'src')).find(file => /^vattsweb\.(tsx|jsx|js|ts)$/.test(file));
|
|
346
298
|
if (instrumentationFile) {
|
|
347
299
|
const instrumentationPath = path_1.default.join(dir, 'src', instrumentationFile);
|
|
348
|
-
// dar require, e executar a função principal do arquivo
|
|
349
300
|
const instrumentation = require(instrumentationPath);
|
|
350
|
-
// Registra o listener de hot reload se existir
|
|
351
301
|
if (instrumentation.hotReloadListener && typeof instrumentation.hotReloadListener === 'function') {
|
|
352
302
|
if (hotReloadManager) {
|
|
353
303
|
hotReloadManager.setHotReloadListener(instrumentation.hotReloadListener);
|
|
@@ -366,17 +316,14 @@ function vatts(options) {
|
|
|
366
316
|
},
|
|
367
317
|
getRequestHandler: () => {
|
|
368
318
|
return async (req, res) => {
|
|
369
|
-
// Detecta o framework e cria request/response genéricos
|
|
370
319
|
const adapter = factory_1.FrameworkAdapterFactory.detectFramework(req, res);
|
|
371
320
|
const genericReq = adapter.parseRequest(req);
|
|
372
321
|
const genericRes = adapter.createResponse(res);
|
|
373
|
-
// Adiciona informações do hweb na requisição genérica
|
|
374
322
|
genericReq.hwebDev = dev;
|
|
375
323
|
genericReq.hotReloadManager = hotReloadManager;
|
|
376
324
|
const { hostname } = req.headers;
|
|
377
325
|
const method = (genericReq.method || 'GET').toUpperCase();
|
|
378
326
|
const pathname = new URL(genericReq.url, `http://${hostname}:${port}`).pathname;
|
|
379
|
-
// RPC endpoint (antes das rotas de backend)
|
|
380
327
|
if (pathname === types_1.RPC_ENDPOINT && method === 'POST') {
|
|
381
328
|
try {
|
|
382
329
|
const result = await (0, server_1.executeRpc)({
|
|
@@ -393,12 +340,9 @@ function vatts(options) {
|
|
|
393
340
|
return;
|
|
394
341
|
}
|
|
395
342
|
}
|
|
396
|
-
// 1. Verifica se é WebSocket upgrade para hot reload
|
|
397
343
|
if (pathname === '/hweb-hotreload/' && genericReq.headers.upgrade === 'websocket' && hotReloadManager) {
|
|
398
|
-
// Framework vai chamar o evento 'upgrade' do servidor HTTP
|
|
399
344
|
return;
|
|
400
345
|
}
|
|
401
|
-
// 2. Primeiro verifica se é um arquivo estático da pasta public
|
|
402
346
|
if (pathname !== '/' && !pathname.startsWith('/api/') && !pathname.startsWith('/.vatts')) {
|
|
403
347
|
const publicDir = path_1.default.join(dir, 'public');
|
|
404
348
|
if (!isSuspiciousPathname(pathname)) {
|
|
@@ -427,7 +371,6 @@ function vatts(options) {
|
|
|
427
371
|
'.zip': 'application/zip'
|
|
428
372
|
};
|
|
429
373
|
genericRes.header('Content-Type', contentTypes[ext] || 'application/octet-stream');
|
|
430
|
-
// Para arquivos estáticos, usamos o método nativo do framework
|
|
431
374
|
if (adapter.type === 'express') {
|
|
432
375
|
res.sendFile(filePath);
|
|
433
376
|
}
|
|
@@ -456,7 +399,6 @@ function vatts(options) {
|
|
|
456
399
|
'.map': 'application/json'
|
|
457
400
|
};
|
|
458
401
|
genericRes.header('Content-Type', contentTypes[ext] || 'text/plain');
|
|
459
|
-
// Para arquivos estáticos, usamos o método nativo do framework
|
|
460
402
|
if (adapter.type === 'express') {
|
|
461
403
|
res.sendFile(filePath);
|
|
462
404
|
}
|
|
@@ -472,18 +414,13 @@ function vatts(options) {
|
|
|
472
414
|
}
|
|
473
415
|
}
|
|
474
416
|
}
|
|
475
|
-
// 4. REMOVIDO: Verificação de arquivos React UMD - não precisamos mais
|
|
476
|
-
// O React agora será bundlado diretamente no main.js
|
|
477
|
-
// 5. Verifica se é uma rota de API (backend)
|
|
478
417
|
const backendMatch = (0, router_1.findMatchingBackendRoute)(pathname, method);
|
|
479
418
|
if (backendMatch) {
|
|
480
419
|
try {
|
|
481
420
|
const handler = backendMatch.route[method];
|
|
482
421
|
if (handler) {
|
|
483
422
|
const hwebReq = new http_1.VattsRequest(genericReq);
|
|
484
|
-
// Executa middlewares e depois o handler final
|
|
485
423
|
const hwebRes = await executeMiddlewareChain(backendMatch.route.middleware, handler, hwebReq, backendMatch.params);
|
|
486
|
-
// Aplica a resposta usando o adapter correto
|
|
487
424
|
hwebRes._applyTo(genericRes);
|
|
488
425
|
return;
|
|
489
426
|
}
|
|
@@ -494,24 +431,41 @@ function vatts(options) {
|
|
|
494
431
|
return;
|
|
495
432
|
}
|
|
496
433
|
}
|
|
497
|
-
//
|
|
434
|
+
// Renderização de Página (Frontend)
|
|
498
435
|
const pageMatch = (0, router_1.findMatchingRoute)(pathname);
|
|
436
|
+
// Determina o objeto de resposta "cru" para o stream do React
|
|
437
|
+
// Se for Fastify, o Writable stream está em res.raw. Se for Express/Native, é o próprio res.
|
|
438
|
+
const rawRes = (res.raw || res);
|
|
499
439
|
if (!pageMatch) {
|
|
500
|
-
// Em vez de enviar texto simples, renderiza a página 404 React
|
|
501
440
|
try {
|
|
502
|
-
// Cria uma "rota falsa" para a página 404
|
|
503
441
|
const notFoundRoute = {
|
|
504
442
|
pattern: '/__404__',
|
|
505
|
-
component: () => null, //
|
|
443
|
+
component: () => null, // Será renderizado via SSR se tiver componente de 404 definido no Client
|
|
506
444
|
componentPath: '__404__'
|
|
507
445
|
};
|
|
508
|
-
|
|
446
|
+
// Tenta usar componente 404 customizado se houver
|
|
447
|
+
const notFound = (0, router_1.getNotFound)();
|
|
448
|
+
if (notFound) {
|
|
449
|
+
// Carrega o componente 404 real para o SSR funcionar
|
|
450
|
+
try {
|
|
451
|
+
const nfModule = require(path_1.default.resolve(process.cwd(), notFound.componentPath));
|
|
452
|
+
// @ts-ignore
|
|
453
|
+
notFoundRoute.component = nfModule.default || nfModule;
|
|
454
|
+
}
|
|
455
|
+
catch (e) { }
|
|
456
|
+
}
|
|
457
|
+
// Define status 404 antes de iniciar o stream
|
|
458
|
+
if (rawRes.statusCode)
|
|
459
|
+
rawRes.statusCode = 404; // Native/Fastify
|
|
460
|
+
if (rawRes.status)
|
|
461
|
+
rawRes.status(404); // Express (mas pode quebrar se for raw, melhor usar statusCode)
|
|
462
|
+
await (0, renderer_1.renderAsStream)({
|
|
509
463
|
req: genericReq,
|
|
464
|
+
res: rawRes,
|
|
510
465
|
route: notFoundRoute,
|
|
511
466
|
params: {},
|
|
512
467
|
allRoutes: frontendRoutes
|
|
513
468
|
});
|
|
514
|
-
genericRes.status(404).header('Content-Type', 'text/html').send(html);
|
|
515
469
|
return;
|
|
516
470
|
}
|
|
517
471
|
catch (error) {
|
|
@@ -521,26 +475,28 @@ function vatts(options) {
|
|
|
521
475
|
}
|
|
522
476
|
}
|
|
523
477
|
try {
|
|
524
|
-
|
|
478
|
+
// Renderização via Stream (SSR + Streaming)
|
|
479
|
+
await (0, renderer_1.renderAsStream)({
|
|
525
480
|
req: genericReq,
|
|
481
|
+
res: rawRes,
|
|
526
482
|
route: pageMatch.route,
|
|
527
483
|
params: pageMatch.params,
|
|
528
484
|
allRoutes: frontendRoutes
|
|
529
485
|
});
|
|
530
|
-
genericRes.status(200).header('Content-Type', 'text/html').send(html);
|
|
531
486
|
}
|
|
532
487
|
catch (error) {
|
|
533
488
|
console_1.default.error(`Error rendering page ${pathname}:`, error);
|
|
534
|
-
|
|
489
|
+
// Se o stream já começou, não dá pra enviar erro 500 limpo.
|
|
490
|
+
// O renderAsStream tenta lidar com isso no onError.
|
|
491
|
+
if (!rawRes.headersSent) {
|
|
492
|
+
genericRes.status(500).text('Internal server error');
|
|
493
|
+
}
|
|
535
494
|
}
|
|
536
495
|
};
|
|
537
496
|
},
|
|
538
|
-
// Método para configurar WebSocket upgrade nos servidores Express e Fastify
|
|
539
497
|
setupWebSocket: (server) => {
|
|
540
|
-
// Detecta se é um servidor Express ou Fastify
|
|
541
498
|
const isExpressServer = factory_1.FrameworkAdapterFactory.getCurrentAdapter() instanceof express_1.ExpressAdapter;
|
|
542
499
|
const actualServer = isExpressServer ? server : (server.server || server);
|
|
543
|
-
// Usa o sistema coordenado de WebSocket upgrade que integra hot-reload e rotas de usuário
|
|
544
500
|
(0, router_1.setupWebSocketUpgrade)(actualServer, hotReloadManager);
|
|
545
501
|
},
|
|
546
502
|
stop: () => {
|
package/dist/renderer.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { RouteConfig } from './types';
|
|
|
2
2
|
import type { GenericRequest } from './types/framework';
|
|
3
3
|
interface RenderOptions {
|
|
4
4
|
req: GenericRequest;
|
|
5
|
+
res: any;
|
|
5
6
|
route: RouteConfig & {
|
|
6
7
|
componentPath: string;
|
|
7
8
|
};
|
|
@@ -10,5 +11,6 @@ interface RenderOptions {
|
|
|
10
11
|
componentPath: string;
|
|
11
12
|
})[];
|
|
12
13
|
}
|
|
13
|
-
export declare function
|
|
14
|
+
export declare function renderAsStream({ req, res, route, params, allRoutes }: RenderOptions): Promise<void>;
|
|
15
|
+
export declare function render(options: any): Promise<string>;
|
|
14
16
|
export {};
|