@ressjs/vite-router 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 gabrielspisso
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,221 @@
1
+ # @ressjs/vite-router
2
+
3
+ Express router factory para SSR automático con detección de páginas y soporte multi-platform.
4
+
5
+ ## Características
6
+
7
+ - 🚀 **Detección automática de páginas** - Escanea `app/pages/` y crea rutas automáticamente
8
+ - 📱 **Soporte multi-platform** - Detecta dispositivos móviles y carga estilos específicos
9
+ - ⚡ **SSR integrado** - Server-Side Rendering usando `@ressjs/core`
10
+ - 🎯 **Entry clients dinámicos** - Genera entry points específicos por platform
11
+ - 🛠️ **Zero-config** - Funciona out-of-the-box con configuración mínima
12
+
13
+ ## Instalación
14
+
15
+ ```bash
16
+ npm install @ressjs/vite-router
17
+ ```
18
+
19
+ ## Uso Básico
20
+
21
+ ```javascript
22
+ import express from 'express'
23
+ import { createViteRouter } from '@ressjs/vite-router'
24
+
25
+ const app = express()
26
+
27
+ // Crear router automático
28
+ const viteRouter = createViteRouter({
29
+ pagesDir: 'app/pages',
30
+ outputDir: 'dist/.entries',
31
+ enableSSR: true,
32
+ enablePlatformDetection: true
33
+ })
34
+
35
+ app.use('/', viteRouter)
36
+ app.listen(3000)
37
+ ```
38
+
39
+ ## Uso Avanzado
40
+
41
+ ```javascript
42
+ import { RouterFactory } from '@ressjs/vite-router'
43
+
44
+ const factory = new RouterFactory({
45
+ pagesDir: 'app/pages',
46
+ outputDir: 'temp',
47
+ enableSSR: true,
48
+ enablePlatformDetection: true,
49
+ staticDir: 'public'
50
+ })
51
+
52
+ // Inicializar antes de usar
53
+ await factory.initialize()
54
+
55
+ const router = factory.createRouter()
56
+ app.use('/', router)
57
+
58
+ // Limpiar al finalizar
59
+ process.on('exit', () => {
60
+ factory.cleanup()
61
+ })
62
+ ```
63
+
64
+ ## Detección de Páginas
65
+
66
+ El router automáticamente detecta páginas en la estructura:
67
+
68
+ ```
69
+ app/pages/
70
+ ├── index.tsx -> ruta: /
71
+ ├── about.tsx -> ruta: /about
72
+ ├── products/
73
+ │ ├── index.tsx -> ruta: /products
74
+ │ └── [id].tsx -> ruta: /products/:id
75
+ └── blog/
76
+ └── post.tsx -> ruta: /blog/post
77
+ ```
78
+
79
+ ## Soporte Multi-Platform
80
+
81
+ ### Estilos específicos por platform
82
+
83
+ ```
84
+ app/pages/home/
85
+ ├── index.tsx
86
+ ├── index.scss -> estilos generales
87
+ ├── index.mobile.scss -> solo móvil
88
+ └── index.desktop.scss -> solo desktop
89
+ ```
90
+
91
+ ### Detección automática
92
+
93
+ El router detecta el device usando el User-Agent y carga estilos específicos:
94
+
95
+ ```javascript
96
+ // En el cliente se añade automáticamente:
97
+ document.documentElement.classList.add('mobile') // o 'desktop'
98
+ ```
99
+
100
+ ## API
101
+
102
+ ### `createViteRouter(options)`
103
+
104
+ Crea un Express Router configurado automáticamente.
105
+
106
+ ```typescript
107
+ interface RouterFactoryOptions {
108
+ pagesDir: string // Directorio de páginas
109
+ outputDir?: string // Directorio para entries generados
110
+ enableSSR?: boolean // Habilitar SSR (default: true)
111
+ enablePlatformDetection?: boolean // Detección de platform (default: true)
112
+ staticDir?: string // Directorio de archivos estáticos
113
+ }
114
+ ```
115
+
116
+ ### `createInitializedViteRouter(options)`
117
+
118
+ Versión async que inicializa automáticamente el router.
119
+
120
+ ### `RouterFactory`
121
+
122
+ Clase para control completo del router.
123
+
124
+ #### Métodos
125
+
126
+ - `initialize()` - Genera entries iniciales
127
+ - `createRouter()` - Crea el Express Router
128
+ - `cleanup()` - Limpia archivos temporales
129
+
130
+ ### `PageDetector`
131
+
132
+ Utilidad para detectar páginas automáticamente.
133
+
134
+ ```javascript
135
+ import { PageDetector } from '@ressjs/vite-router'
136
+
137
+ const detector = new PageDetector({
138
+ pagesDir: 'app/pages'
139
+ })
140
+
141
+ const pages = await detector.getDetectedPages()
142
+ const match = detector.matchRoute('/products/123', pages)
143
+ ```
144
+
145
+ ### `EntryGenerator`
146
+
147
+ Generador de entry clients dinámicos.
148
+
149
+ ```javascript
150
+ import { EntryGenerator } from '@ressjs/vite-router'
151
+
152
+ const generator = new EntryGenerator({
153
+ pagesDir: 'app/pages',
154
+ outputDir: 'dist/.entries'
155
+ })
156
+
157
+ const platform = generator.detectPlatformFromRequest(req)
158
+ const entry = await generator.generatePlatformSpecificEntry(
159
+ '/products',
160
+ platform,
161
+ pages
162
+ )
163
+ ```
164
+
165
+ ## Integración con Vite
166
+
167
+ Ejemplo completo con Vite development server:
168
+
169
+ ```javascript
170
+ import fs from 'node:fs/promises'
171
+ import express from 'express'
172
+ import { createInitializedViteRouter } from '@ressjs/vite-router'
173
+
174
+ const isProduction = process.env.NODE_ENV === 'production'
175
+ const app = express()
176
+
177
+ let vite
178
+ if (!isProduction) {
179
+ const { createServer } = await import('vite')
180
+ vite = await createServer({
181
+ server: { middlewareMode: true },
182
+ appType: 'custom'
183
+ })
184
+ app.use(vite.middlewares)
185
+ }
186
+
187
+ // Router automático con SSR
188
+ const viteRouter = await createInitializedViteRouter({
189
+ pagesDir: 'app/pages',
190
+ enableSSR: true,
191
+ enablePlatformDetection: true
192
+ })
193
+
194
+ app.use('/', viteRouter)
195
+ app.listen(3000)
196
+ ```
197
+
198
+ ## Middleware Stack
199
+
200
+ El router crea automáticamente el siguiente stack de middleware:
201
+
202
+ 1. **Page Detection** - Detecta páginas y prepara contexto
203
+ 2. **Platform Detection** - Detecta dispositivo (móvil/desktop)
204
+ 3. **Entry Generation** - Genera entry client específico
205
+ 4. **SSR Rendering** - Renderiza servidor-side con React
206
+ 5. **Static Files** - Fallback para archivos estáticos
207
+
208
+ ## Tipos TypeScript
209
+
210
+ ```typescript
211
+ import type {
212
+ RouterFactoryOptions,
213
+ RouteContext,
214
+ PageRouterInfo,
215
+ EntryGeneratorOptions
216
+ } from '@ressjs/vite-router'
217
+ ```
218
+
219
+ ## Ejemplos
220
+
221
+ Ver `/examples/basic-ssr/` para un ejemplo completo de uso.
@@ -0,0 +1,34 @@
1
+ import { PageInfo } from '@ressjs/core';
2
+ import { Request as ExpressRequest } from 'express';
3
+ export interface EntryGeneratorOptions {
4
+ pagesDir: string;
5
+ outputDir?: string;
6
+ platform?: 'desktop' | 'mobile';
7
+ }
8
+ export declare class EntryGenerator {
9
+ private options;
10
+ constructor(options: EntryGeneratorOptions);
11
+ /**
12
+ * Genera entry-client dinámicos para las páginas detectadas
13
+ */
14
+ generateDynamicEntries(): Promise<string[]>;
15
+ /**
16
+ * Detecta el platform basado en el user-agent de la request
17
+ */
18
+ detectPlatformFromRequest(req: ExpressRequest): 'desktop' | 'mobile';
19
+ /**
20
+ * Genera entry específico para un platform
21
+ */
22
+ generatePlatformSpecificEntry(pageRoute: string, platform: 'desktop' | 'mobile', pages: PageInfo[]): Promise<string>;
23
+ /**
24
+ * Escribe entry files al filesystem
25
+ */
26
+ writeEntryFiles(entries: {
27
+ [key: string]: string;
28
+ }): Promise<void>;
29
+ /**
30
+ * Limpia archivos temporales generados
31
+ */
32
+ cleanup(): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=entry-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-generator.d.ts","sourceRoot":"","sources":["../src/entry-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAChC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAiC;gBAEpC,OAAO,EAAE,qBAAqB;IAQ1C;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIjD;;OAEG;IACH,yBAAyB,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,GAAG,QAAQ;IAUpE;;OAEG;IACG,6BAA6B,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAC9B,KAAK,EAAE,QAAQ,EAAE,GAChB,OAAO,CAAC,MAAM,CAAC;IAuElB;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ/B"}
@@ -0,0 +1,113 @@
1
+ import { generateTempEntries } from '@ressjs/core';
2
+ export class EntryGenerator {
3
+ constructor(options) {
4
+ this.options = {
5
+ outputDir: 'temp',
6
+ platform: 'desktop',
7
+ ...options
8
+ };
9
+ }
10
+ /**
11
+ * Genera entry-client dinámicos para las páginas detectadas
12
+ */
13
+ async generateDynamicEntries() {
14
+ return generateTempEntries(this.options.outputDir);
15
+ }
16
+ /**
17
+ * Detecta el platform basado en el user-agent de la request
18
+ */
19
+ detectPlatformFromRequest(req) {
20
+ const userAgent = req.headers['user-agent']?.toLowerCase() || '';
21
+ // Simple mobile detection
22
+ const mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone'];
23
+ const isMobile = mobileKeywords.some(keyword => userAgent.includes(keyword));
24
+ return isMobile ? 'mobile' : 'desktop';
25
+ }
26
+ /**
27
+ * Genera entry específico para un platform
28
+ */
29
+ async generatePlatformSpecificEntry(pageRoute, platform, pages) {
30
+ const page = pages.find(p => p.route === pageRoute);
31
+ if (!page) {
32
+ throw new Error(`Page ${pageRoute} not found`);
33
+ }
34
+ // Detectar archivos de estilos relacionados con la página
35
+ const fs = await import('fs/promises');
36
+ const path = await import('path');
37
+ const pageDir = path.dirname(page.file);
38
+ const baseName = path.basename(page.file, path.extname(page.file));
39
+ // Buscar archivos de estilos
40
+ const possibleStyles = [
41
+ path.join(pageDir, `${baseName}.scss`),
42
+ path.join(pageDir, `${baseName}.css`),
43
+ path.join(pageDir, `${baseName}.${platform}.scss`),
44
+ path.join(pageDir, `${baseName}.${platform}.css`),
45
+ path.join(pageDir, 'index.scss'),
46
+ path.join(pageDir, 'index.css'),
47
+ path.join(pageDir, `index.${platform}.scss`),
48
+ path.join(pageDir, `index.${platform}.css`)
49
+ ];
50
+ const existingStyles = [];
51
+ for (const stylePath of possibleStyles) {
52
+ try {
53
+ await fs.access(stylePath);
54
+ existingStyles.push(stylePath);
55
+ }
56
+ catch {
57
+ // Archivo no existe, continuar
58
+ }
59
+ }
60
+ // Separar estilos generales de platform-specific
61
+ const generalStyles = existingStyles.filter(style => !style.includes(`.${platform}.`) &&
62
+ !style.includes('.mobile.') &&
63
+ !style.includes('.desktop.'));
64
+ const platformStyles = existingStyles.filter(style => style.includes(`.${platform}.`));
65
+ // Generar el entry client dinámicamente
66
+ const entryContent = `
67
+ import React from 'react'
68
+ import { createRoot } from 'react-dom/client'
69
+ import Page from '${page.abs}'
70
+ ${generalStyles.map(style => `import '${style}'`).join('\n')}
71
+ ${platformStyles.map(style => `import '${style}'`).join('\n')}
72
+
73
+ // Platform-specific styles
74
+ document.documentElement.classList.add('${platform}')
75
+
76
+ const container = document.getElementById('root')
77
+ if (container) {
78
+ const root = createRoot(container)
79
+
80
+ // Hydrate con props del servidor si están disponibles
81
+ const serverProps = (window as any).__SERVER_PROPS__ || {}
82
+
83
+ root.render(React.createElement(Page, serverProps))
84
+ }
85
+ `;
86
+ return entryContent.trim();
87
+ }
88
+ /**
89
+ * Escribe entry files al filesystem
90
+ */
91
+ async writeEntryFiles(entries) {
92
+ const fs = await import('fs/promises');
93
+ const path = await import('path');
94
+ await fs.mkdir(this.options.outputDir, { recursive: true });
95
+ for (const [filename, content] of Object.entries(entries)) {
96
+ const filepath = path.join(this.options.outputDir, `${filename}.tsx`);
97
+ await fs.writeFile(filepath, content, 'utf-8');
98
+ }
99
+ }
100
+ /**
101
+ * Limpia archivos temporales generados
102
+ */
103
+ async cleanup() {
104
+ const fs = await import('fs/promises');
105
+ try {
106
+ await fs.rm(this.options.outputDir, { recursive: true, force: true });
107
+ }
108
+ catch (error) {
109
+ // Ignorar errores si el directorio no existe
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=entry-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-generator.js","sourceRoot":"","sources":["../src/entry-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { createViteRouter, createAutoViteServer, detectPlatform, listDetectedPages, getPages } from './simple-router.js';
2
+ export type { ViteRouterOptions, AutoViteServerOptions } from './simple-router.js';
3
+ export { RouterFactory, createInitializedViteRouter } from './router-factory.js';
4
+ export { PageDetector } from './page-detector.js';
5
+ export { EntryGenerator } from './entry-generator.js';
6
+ export type { RouterFactoryOptions, RouteContext } from './router-factory.js';
7
+ export type { RouterOptions, PageRouterInfo } from './page-detector.js';
8
+ export type { EntryGeneratorOptions } from './entry-generator.js';
9
+ export type { PageInfo } from '@ressjs/core';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACT,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAGlF,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC7E,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAGjE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // Main API - Versión simplificada que funciona con el servidor existente
2
+ export { createViteRouter, createAutoViteServer, detectPlatform, listDetectedPages, getPages } from './simple-router.js';
3
+ // Legacy exports para compatibilidad (deprecated)
4
+ export { RouterFactory, createInitializedViteRouter } from './router-factory.js';
5
+ export { PageDetector } from './page-detector.js';
6
+ export { EntryGenerator } from './entry-generator.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACT,MAAM,oBAAoB,CAAA;AAI3B,kDAAkD;AAClD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,44 @@
1
+ import { PageInfo } from '@ressjs/core';
2
+ import { Request } from 'express';
3
+ export interface RouterOptions {
4
+ distPath?: string;
5
+ pagesDir?: string;
6
+ renderFunction?: (url: string) => Promise<{
7
+ html: string;
8
+ props: any;
9
+ }>;
10
+ }
11
+ export interface PageRouterInfo extends PageInfo {
12
+ entryPath?: string;
13
+ }
14
+ export declare class PageDetector {
15
+ private distPath;
16
+ private pagesDir;
17
+ constructor(options?: RouterOptions);
18
+ /**
19
+ * Detecta todas las páginas disponibles
20
+ */
21
+ getDetectedPages(): PageRouterInfo[];
22
+ /**
23
+ * Genera entry-clients para todas las páginas
24
+ */
25
+ generatePageEntries(): Promise<void>;
26
+ /**
27
+ * Obtiene input para Vite client build
28
+ */
29
+ getClientBuildInput(): Promise<Record<string, string>>;
30
+ /**
31
+ * Detecta la plataforma desde el user agent
32
+ */
33
+ detectPlatform(req: Request): string;
34
+ /**
35
+ * Encuentra una página por su ruta
36
+ */
37
+ findPageByRoute(route: string): PageRouterInfo | undefined;
38
+ private getEntryPath;
39
+ /**
40
+ * Encuentra la página que coincide con una ruta específica
41
+ */
42
+ matchRoute(requestPath: string, pages: PageInfo[]): PageInfo | null;
43
+ }
44
+ //# sourceMappingURL=page-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-detector.d.ts","sourceRoot":"","sources":["../src/page-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,QAAQ,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAIjC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,CAAA;CACxE;AAED,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAQ;gBAEZ,OAAO,GAAE,aAAkB;IAKvC;;OAEG;IACI,gBAAgB,IAAI,cAAc,EAAE;IAsB3C;;OAEG;IACU,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjD;;OAEG;IACU,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAInE;;OAEG;IACI,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM;IAO3C;;OAEG;IACI,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAQjE,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI;CAuBpE"}
@@ -0,0 +1,92 @@
1
+ import { generateTempEntries, getClientEntriesInput } from '@ressjs/core';
2
+ import glob from 'fast-glob';
3
+ import { resolve } from 'path';
4
+ export class PageDetector {
5
+ constructor(options = {}) {
6
+ this.distPath = options.distPath || 'dist';
7
+ this.pagesDir = options.pagesDir || 'app/pages';
8
+ }
9
+ /**
10
+ * Detecta todas las páginas disponibles
11
+ */
12
+ getDetectedPages() {
13
+ // Busca tanto page.tsx como page/index.tsx y prioriza el más corto
14
+ const files = glob.sync(`${this.pagesDir}/**/*.{tsx,jsx}`);
15
+ const seen = new Set();
16
+ const pages = [];
17
+ for (const file of files) {
18
+ let route = file.replace(new RegExp(`^${this.pagesDir}`), '').replace(/\.tsx$|\.jsx$/, '');
19
+ route = route.replace(/\/index$/, '') || '/';
20
+ // Prioriza page.tsx sobre page/index.tsx
21
+ if (!seen.has(route)) {
22
+ seen.add(route);
23
+ pages.push({ route, file, abs: resolve(file) });
24
+ }
25
+ }
26
+ return pages.map(page => ({
27
+ ...page,
28
+ entryPath: this.getEntryPath(page)
29
+ }));
30
+ }
31
+ /**
32
+ * Genera entry-clients para todas las páginas
33
+ */
34
+ async generatePageEntries() {
35
+ await generateTempEntries(this.distPath);
36
+ }
37
+ /**
38
+ * Obtiene input para Vite client build
39
+ */
40
+ async getClientBuildInput() {
41
+ return await getClientEntriesInput(this.distPath);
42
+ }
43
+ /**
44
+ * Detecta la plataforma desde el user agent
45
+ */
46
+ detectPlatform(req) {
47
+ const ua = req.headers['user-agent'] || '';
48
+ if (/mobile|android|iphone|ipad|phone/i.test(ua))
49
+ return 'mobile';
50
+ if (/linux/i.test(ua))
51
+ return 'desktop.linux';
52
+ return 'desktop';
53
+ }
54
+ /**
55
+ * Encuentra una página por su ruta
56
+ */
57
+ findPageByRoute(route) {
58
+ const pages = this.getDetectedPages();
59
+ return pages.find(page => {
60
+ if (page.route === '/')
61
+ return route === '/' || route === '';
62
+ return route === page.route || route.startsWith(page.route + '/');
63
+ });
64
+ }
65
+ getEntryPath(page) {
66
+ const rel = page.file.replace(/^app\/pages\//, '').replace(/\.tsx$|\.jsx$/, '');
67
+ return `${this.distPath}/.entries/${rel}__entry-client.tsx`;
68
+ }
69
+ /**
70
+ * Encuentra la página que coincide con una ruta específica
71
+ */
72
+ matchRoute(requestPath, pages) {
73
+ // Normalizar la ruta de request
74
+ const normalizedPath = requestPath === '/' ? '/' : requestPath.replace(/\/$/, '');
75
+ // Buscar coincidencia exacta primero
76
+ let match = pages.find(page => page.route === normalizedPath);
77
+ // Si no hay coincidencia exacta, buscar rutas dinámicas o wildcards
78
+ if (!match) {
79
+ // Para rutas como /page1, /page2, etc.
80
+ match = pages.find(page => {
81
+ // Convertir ruta de página a regex para matching
82
+ const routePattern = page.route
83
+ .replace(/\[([^\]]+)\]/g, '([^/]+)') // [param] -> captura
84
+ .replace(/\*/g, '.*'); // * -> wildcard
85
+ const regex = new RegExp(`^${routePattern}$`);
86
+ return regex.test(normalizedPath);
87
+ });
88
+ }
89
+ return match || null;
90
+ }
91
+ }
92
+ //# sourceMappingURL=page-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-detector.js","sourceRoot":"","sources":["../src/page-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { Router } from 'express';
2
+ import { PageInfo } from '@ressjs/core';
3
+ export interface RouterFactoryOptions {
4
+ pagesDir: string;
5
+ outputDir?: string;
6
+ enableSSR?: boolean;
7
+ enablePlatformDetection?: boolean;
8
+ staticDir?: string;
9
+ }
10
+ export interface RouteContext {
11
+ page: PageInfo;
12
+ platform: 'desktop' | 'mobile';
13
+ entry: string;
14
+ }
15
+ export declare class RouterFactory {
16
+ private options;
17
+ private pageDetector;
18
+ private entryGenerator;
19
+ private renderServer;
20
+ constructor(options: RouterFactoryOptions);
21
+ /**
22
+ * Crea un Express Router con todas las rutas automáticas
23
+ */
24
+ createRouter(): Router;
25
+ /**
26
+ * Middleware para detectar páginas y preparar context
27
+ */
28
+ private pageDetectionMiddleware;
29
+ /**
30
+ * Middleware para Server-Side Rendering
31
+ */
32
+ private ssrMiddleware;
33
+ /**
34
+ * Middleware para archivos estáticos
35
+ */
36
+ private staticMiddleware;
37
+ /**
38
+ * Inyecta el entry client específico del platform en el HTML
39
+ */
40
+ private injectClientEntry;
41
+ /**
42
+ * Limpia archivos temporales
43
+ */
44
+ cleanup(): Promise<void>;
45
+ /**
46
+ * Inicializa el router (genera entries iniciales)
47
+ */
48
+ initialize(): Promise<void>;
49
+ }
50
+ /**
51
+ * Factory function para crear un router fácilmente
52
+ */
53
+ export declare function createViteRouter(options: RouterFactoryOptions): Router;
54
+ /**
55
+ * Factory function async para inicializar y crear el router
56
+ */
57
+ export declare function createInitializedViteRouter(options: RouterFactoryOptions): Promise<Router>;
58
+ //# sourceMappingURL=router-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-factory.d.ts","sourceRoot":"","sources":["../src/router-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAA;AAGjE,OAAO,EAAsB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE3D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAA;IACd,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,YAAY,CAAK;gBAEb,OAAO,EAAE,oBAAoB;IAwBzC;;OAEG;IACH,YAAY,IAAI,MAAM;IAiBtB;;OAEG;YACW,uBAAuB;IAiDrC;;OAEG;YACW,aAAa;IA4B3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqBzB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGlC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAGtE;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIhG"}
@@ -0,0 +1,153 @@
1
+ import { Router } from 'express';
2
+ import { PageDetector } from './page-detector.js';
3
+ import { EntryGenerator } from './entry-generator.js';
4
+ import { createRenderServer } from '@ressjs/core';
5
+ export class RouterFactory {
6
+ constructor(options) {
7
+ this.options = {
8
+ outputDir: 'temp',
9
+ enableSSR: true,
10
+ enablePlatformDetection: true,
11
+ staticDir: 'public',
12
+ ...options
13
+ };
14
+ this.pageDetector = new PageDetector({
15
+ pagesDir: this.options.pagesDir,
16
+ distPath: this.options.outputDir
17
+ });
18
+ this.entryGenerator = new EntryGenerator({
19
+ pagesDir: this.options.pagesDir,
20
+ outputDir: this.options.outputDir
21
+ });
22
+ if (this.options.enableSSR) {
23
+ this.renderServer = createRenderServer();
24
+ }
25
+ }
26
+ /**
27
+ * Crea un Express Router con todas las rutas automáticas
28
+ */
29
+ createRouter() {
30
+ const router = Router();
31
+ // Middleware para detectar páginas y generar entries
32
+ router.use(this.pageDetectionMiddleware.bind(this));
33
+ // Middleware para SSR
34
+ if (this.options.enableSSR) {
35
+ router.use(this.ssrMiddleware.bind(this));
36
+ }
37
+ // Fallback para servir archivos estáticos
38
+ router.use(this.staticMiddleware.bind(this));
39
+ return router;
40
+ }
41
+ /**
42
+ * Middleware para detectar páginas y preparar context
43
+ */
44
+ async pageDetectionMiddleware(req, _res, next) {
45
+ try {
46
+ console.log(`[ViteRouter] Processing request: ${req.path}`);
47
+ const detectedPages = await this.pageDetector.getDetectedPages();
48
+ console.log(`[ViteRouter] Detected ${detectedPages.length} pages:`, detectedPages.map(p => p.route));
49
+ const matchedPage = this.pageDetector.matchRoute(req.path, detectedPages);
50
+ console.log(`[ViteRouter] Matched page for ${req.path}:`, matchedPage);
51
+ if (!matchedPage) {
52
+ console.log(`[ViteRouter] No page matched for ${req.path}, passing to next middleware`);
53
+ return next();
54
+ }
55
+ // Detectar platform si está habilitado
56
+ const platform = this.options.enablePlatformDetection
57
+ ? this.entryGenerator.detectPlatformFromRequest(req)
58
+ : 'desktop';
59
+ console.log(`[ViteRouter] Detected platform: ${platform}`);
60
+ // Generar entry específico para este platform
61
+ const entry = await this.entryGenerator.generatePlatformSpecificEntry(matchedPage.route, platform, detectedPages);
62
+ console.log(`[ViteRouter] Generated entry for ${matchedPage.route}`);
63
+ req.routeContext = {
64
+ page: matchedPage,
65
+ platform,
66
+ entry
67
+ };
68
+ next();
69
+ }
70
+ catch (error) {
71
+ console.error('Error in page detection middleware:', error);
72
+ next(error);
73
+ }
74
+ }
75
+ /**
76
+ * Middleware para Server-Side Rendering
77
+ */
78
+ async ssrMiddleware(req, res, next) {
79
+ const context = req.routeContext;
80
+ if (!context) {
81
+ return next();
82
+ }
83
+ try {
84
+ console.log(`[ViteRouter] SSR rendering for ${req.url}`);
85
+ // Usar el renderServer del core con la URL
86
+ const html = await this.renderServer({ url: req.url });
87
+ // Inyectar el entry client específico del platform
88
+ const finalHtml = this.injectClientEntry(html, context);
89
+ res.setHeader('Content-Type', 'text/html');
90
+ res.send(finalHtml);
91
+ }
92
+ catch (error) {
93
+ console.error('SSR Error:', error);
94
+ next(error);
95
+ }
96
+ }
97
+ /**
98
+ * Middleware para archivos estáticos
99
+ */
100
+ staticMiddleware(_req, _res, next) {
101
+ // Si llegamos aquí, no se encontró una página
102
+ // Express.static se encargará de servir archivos estáticos
103
+ next();
104
+ }
105
+ /**
106
+ * Inyecta el entry client específico del platform en el HTML
107
+ */
108
+ injectClientEntry(html, context) {
109
+ // Buscar el punto de inserción del script
110
+ const scriptInsertPoint = html.indexOf('</head>');
111
+ if (scriptInsertPoint === -1) {
112
+ return html;
113
+ }
114
+ // Generar script tag con el entry específico
115
+ const scriptTag = `
116
+ <script>
117
+ // Platform detection
118
+ document.documentElement.classList.add('${context.platform}')
119
+
120
+ // Entry específico del platform
121
+ ${context.entry}
122
+ </script>`;
123
+ return html.slice(0, scriptInsertPoint) + scriptTag + html.slice(scriptInsertPoint);
124
+ }
125
+ /**
126
+ * Limpia archivos temporales
127
+ */
128
+ async cleanup() {
129
+ await this.entryGenerator.cleanup();
130
+ }
131
+ /**
132
+ * Inicializa el router (genera entries iniciales)
133
+ */
134
+ async initialize() {
135
+ await this.entryGenerator.generateDynamicEntries();
136
+ }
137
+ }
138
+ /**
139
+ * Factory function para crear un router fácilmente
140
+ */
141
+ export function createViteRouter(options) {
142
+ const factory = new RouterFactory(options);
143
+ return factory.createRouter();
144
+ }
145
+ /**
146
+ * Factory function async para inicializar y crear el router
147
+ */
148
+ export async function createInitializedViteRouter(options) {
149
+ const factory = new RouterFactory(options);
150
+ await factory.initialize();
151
+ return factory.createRouter();
152
+ }
153
+ //# sourceMappingURL=router-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-factory.js","sourceRoot":"","sources":["../src/router-factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Router } from 'express';
2
+ export interface ViteRouterOptions {
3
+ enablePlatformDetection?: boolean;
4
+ vite?: any;
5
+ manifest?: any;
6
+ templateHtml?: string;
7
+ isProduction?: boolean;
8
+ renderFunction?: (options: {
9
+ url: string;
10
+ platform: string;
11
+ req: any;
12
+ }) => Promise<string>;
13
+ }
14
+ export interface AutoViteServerOptions {
15
+ port?: number;
16
+ base?: string;
17
+ enablePlatformDetection?: boolean;
18
+ }
19
+ /**
20
+ * Crea un servidor Express completo con vite-router automático
21
+ * Esta es la función de alto nivel para casos simples
22
+ */
23
+ export declare function createAutoViteServer(options?: AutoViteServerOptions): Promise<{
24
+ app: import("express-serve-static-core").Express;
25
+ vite: any;
26
+ start: () => import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
27
+ }>;
28
+ /**
29
+ * Crea un Express router que automáticamente detecta páginas, las rutea,
30
+ * y maneja todo el SSR + hidratación del cliente.
31
+ *
32
+ * Si no se pasan opciones, auto-configura Vite, manifest, templates, etc.
33
+ */
34
+ export declare function createViteRouter(options?: ViteRouterOptions): Router;
35
+ /**
36
+ * Detecta platform desde el User-Agent
37
+ */
38
+ export declare function detectPlatform(userAgent: string): 'desktop' | 'mobile';
39
+ /**
40
+ * Helper para listar páginas detectadas
41
+ */
42
+ export declare function listDetectedPages(): import("@ressjs/core").PageInfo[];
43
+ export { getPages } from '@ressjs/core';
44
+ //# sourceMappingURL=simple-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-router.d.ts","sourceRoot":"","sources":["../src/simple-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAKhC,MAAM,WAAW,iBAAiB;IAChC,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC3F;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B;;;;GA6E7E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAWxE;AAgTD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAItE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,sCAEhC;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,341 @@
1
+ import { Router } from 'express';
2
+ import { getPages, createRenderServer, generateTempEntries } from '@ressjs/core';
3
+ import fs from 'node:fs/promises';
4
+ import express from 'express';
5
+ /**
6
+ * Crea un servidor Express completo con vite-router automático
7
+ * Esta es la función de alto nivel para casos simples
8
+ */
9
+ export async function createAutoViteServer(options = {}) {
10
+ const { port = 5173, base = '/', enablePlatformDetection = true } = options;
11
+ const isProduction = process.env.NODE_ENV === 'production';
12
+ const app = express();
13
+ let vite;
14
+ let manifest = {};
15
+ let templateHtml = '';
16
+ // Configuración automática de Vite
17
+ if (!isProduction) {
18
+ console.log('[AutoViteServer] Setting up development server...');
19
+ const { createServer } = await import('vite');
20
+ vite = await createServer({
21
+ server: { middlewareMode: true },
22
+ appType: 'custom',
23
+ base,
24
+ });
25
+ app.use(vite.middlewares);
26
+ // Sirve los entry-client generados en dev (incluyendo los específicos por plataforma)
27
+ app.use('/dist/.entries', express.static('dist/.entries'));
28
+ // Cargar manifest si existe
29
+ try {
30
+ manifest = JSON.parse(await fs.readFile('./dist/server/.vite/manifest.json', 'utf-8'));
31
+ }
32
+ catch {
33
+ console.log('[AutoViteServer] No server manifest found (normal in dev)');
34
+ manifest = {};
35
+ }
36
+ // Generar entries automáticamente
37
+ await generateTempEntries();
38
+ }
39
+ else {
40
+ console.log('[AutoViteServer] Setting up production server...');
41
+ const compression = (await import('compression')).default;
42
+ const sirv = (await import('sirv')).default;
43
+ app.use(compression());
44
+ app.use(base, sirv('./dist/client', { extensions: [] }));
45
+ // Cargar assets de producción
46
+ manifest = JSON.parse(await fs.readFile('./dist/client/.vite/manifest.json', 'utf-8'));
47
+ templateHtml = await fs.readFile('./index.html', 'utf-8');
48
+ }
49
+ // Crear vite-router con configuración automática
50
+ const viteRouter = createViteRouter({
51
+ enablePlatformDetection,
52
+ vite,
53
+ manifest,
54
+ templateHtml,
55
+ isProduction
56
+ });
57
+ app.use('/', viteRouter);
58
+ app.use(express.static('public'));
59
+ // Función para iniciar el servidor
60
+ const start = () => {
61
+ return app.listen(port, () => {
62
+ const pages = getPages();
63
+ console.log(`🚀 Auto Vite Server started at http://localhost:${port}`);
64
+ console.log(`📄 Auto-detected routes:`);
65
+ pages.forEach(page => {
66
+ console.log(` ${page.route} -> ${page.file}`);
67
+ });
68
+ });
69
+ };
70
+ return { app, vite, start };
71
+ }
72
+ /**
73
+ * Crea un Express router que automáticamente detecta páginas, las rutea,
74
+ * y maneja todo el SSR + hidratación del cliente.
75
+ *
76
+ * Si no se pasan opciones, auto-configura Vite, manifest, templates, etc.
77
+ */
78
+ export function createViteRouter(options = {}) {
79
+ // Si no se pasan opciones críticas, configurar automáticamente
80
+ const needsAutoConfig = !options.vite && !options.manifest && !options.templateHtml;
81
+ if (needsAutoConfig) {
82
+ console.log('[ViteRouter] Auto-configuring...');
83
+ return createAutoConfiguredRouter(options);
84
+ }
85
+ // Configuración manual (para casos avanzados)
86
+ return createManualRouter(options);
87
+ }
88
+ /**
89
+ * Router con configuración automática
90
+ */
91
+ function createAutoConfiguredRouter(options) {
92
+ const { enablePlatformDetection = true, renderFunction } = options;
93
+ const isProduction = process.env.NODE_ENV === 'production';
94
+ let vite;
95
+ let manifest = {};
96
+ let templateHtml = '';
97
+ let renderServer = null;
98
+ let initialized = false;
99
+ // Router principal que va a manejar todo
100
+ const mainRouter = Router();
101
+ // Función para inicializar una sola vez
102
+ const initializeIfNeeded = async () => {
103
+ if (initialized)
104
+ return { vite, manifest, templateHtml };
105
+ if (!isProduction) {
106
+ console.log('[ViteRouter] Setting up development mode...');
107
+ const { createServer } = await import('vite');
108
+ vite = await createServer({
109
+ server: { middlewareMode: true },
110
+ appType: 'custom',
111
+ base: process.env.BASE || '/',
112
+ });
113
+ // Agregar Vite middleware al router principal
114
+ mainRouter.use(vite.middlewares);
115
+ // Cargar manifest si existe
116
+ try {
117
+ manifest = JSON.parse(await fs.readFile('./dist/server/.vite/manifest.json', 'utf-8'));
118
+ }
119
+ catch {
120
+ console.log('[ViteRouter] No server manifest found (normal in dev)');
121
+ manifest = {};
122
+ }
123
+ // Generar entries automáticamente
124
+ await generateTempEntries();
125
+ }
126
+ else {
127
+ console.log('[ViteRouter] Setting up production mode...');
128
+ // Configurar middleware de producción
129
+ const compression = (await import('compression')).default;
130
+ const sirv = (await import('sirv')).default;
131
+ mainRouter.use(compression());
132
+ mainRouter.use(sirv('./dist/client', { extensions: [] }));
133
+ // Cargar assets de producción
134
+ manifest = JSON.parse(await fs.readFile('./dist/client/.vite/manifest.json', 'utf-8'));
135
+ templateHtml = await fs.readFile('./index.html', 'utf-8');
136
+ }
137
+ initialized = true;
138
+ return { vite, manifest, templateHtml };
139
+ };
140
+ // Crear las rutas de páginas
141
+ const pages = getPages();
142
+ console.log(`[ViteRouter] Creating auto-configured router for ${pages.length} pages`);
143
+ pages.forEach(page => {
144
+ console.log(`[ViteRouter] Route: ${page.route} -> ${page.file}`);
145
+ mainRouter.get(page.route, async (req, res, next) => {
146
+ try {
147
+ // Inicializar si es necesario (lazy initialization)
148
+ await initializeIfNeeded();
149
+ // Detectar platform
150
+ let platform = 'desktop';
151
+ if (enablePlatformDetection) {
152
+ const userAgent = req.headers['user-agent']?.toLowerCase() || '';
153
+ const isMobile = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone']
154
+ .some(keyword => userAgent.includes(keyword));
155
+ platform = isMobile ? 'mobile' : 'desktop';
156
+ }
157
+ // Si hay función de render personalizada, usarla
158
+ if (renderFunction) {
159
+ const html = await renderFunction({ url: req.url, platform, req });
160
+ res.setHeader('Content-Type', 'text/html');
161
+ res.send(html);
162
+ return;
163
+ }
164
+ // Crear renderServer lazy-loading
165
+ if (!renderServer) {
166
+ const renderOptions = vite ? { vite } : {};
167
+ renderServer = createRenderServer(renderOptions);
168
+ }
169
+ // Renderizar
170
+ const urlObj = new URL(req.url, 'http://localhost');
171
+ const pathname = urlObj.pathname;
172
+ const rendered = await renderServer({ url: pathname });
173
+ // Obtener template
174
+ let template;
175
+ if (!isProduction) {
176
+ template = await fs.readFile('./index.html', 'utf-8');
177
+ template = await vite.transformIndexHtml(req.url, template);
178
+ }
179
+ else {
180
+ template = templateHtml;
181
+ }
182
+ // Generar HTML completo
183
+ const html = generateFullHTML(template, rendered, page, manifest, platform, isProduction);
184
+ res.setHeader('Content-Type', 'text/html');
185
+ res.send(html);
186
+ }
187
+ catch (error) {
188
+ console.error(`[ViteRouter] Error handling ${req.url}:`, error);
189
+ if (vite?.ssrFixStacktrace) {
190
+ vite.ssrFixStacktrace(error);
191
+ }
192
+ next(error);
193
+ }
194
+ });
195
+ });
196
+ return mainRouter;
197
+ }
198
+ /**
199
+ * Router con configuración manual (para casos avanzados)
200
+ */
201
+ function createManualRouter(options) {
202
+ const { enablePlatformDetection = true, vite, manifest = {}, templateHtml = '', isProduction = process.env.NODE_ENV === 'production', renderFunction } = options;
203
+ const router = Router();
204
+ const pages = getPages();
205
+ let renderServer = null;
206
+ console.log(`[ViteRouter] Creating router for ${pages.length} pages`);
207
+ pages.forEach(page => {
208
+ console.log(`[ViteRouter] Route: ${page.route} -> ${page.file}`);
209
+ router.get(page.route, async (req, res, next) => {
210
+ try {
211
+ // Detectar platform
212
+ let platform = 'desktop';
213
+ if (enablePlatformDetection) {
214
+ const userAgent = req.headers['user-agent']?.toLowerCase() || '';
215
+ const isMobile = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone']
216
+ .some(keyword => userAgent.includes(keyword));
217
+ platform = isMobile ? 'mobile' : 'desktop';
218
+ }
219
+ // Si hay función de render personalizada, usarla
220
+ if (renderFunction) {
221
+ const html = await renderFunction({ url: req.url, platform, req });
222
+ res.setHeader('Content-Type', 'text/html');
223
+ res.send(html);
224
+ return;
225
+ }
226
+ // Crear renderServer lazy-loading
227
+ if (!renderServer) {
228
+ const renderOptions = vite ? { vite } : {};
229
+ renderServer = createRenderServer(renderOptions);
230
+ }
231
+ // Renderizar
232
+ const urlObj = new URL(req.url, 'http://localhost');
233
+ const pathname = urlObj.pathname;
234
+ const rendered = await renderServer({ url: pathname });
235
+ // Obtener template
236
+ let template;
237
+ if (!isProduction) {
238
+ template = await fs.readFile('./index.html', 'utf-8');
239
+ template = await vite.transformIndexHtml(req.url, template);
240
+ }
241
+ else {
242
+ template = templateHtml;
243
+ }
244
+ // Generar HTML completo
245
+ const html = generateFullHTML(template, rendered, page, manifest, platform, isProduction);
246
+ res.setHeader('Content-Type', 'text/html');
247
+ res.send(html);
248
+ }
249
+ catch (error) {
250
+ console.error(`[ViteRouter] Error handling ${req.url}:`, error);
251
+ if (vite?.ssrFixStacktrace) {
252
+ vite.ssrFixStacktrace(error);
253
+ }
254
+ next(error);
255
+ }
256
+ });
257
+ });
258
+ return router;
259
+ }
260
+ /**
261
+ * Genera el HTML completo con assets y hidratación
262
+ */
263
+ function generateFullHTML(template, rendered, page, manifest, platform, isProduction) {
264
+ // Función para obtener script del cliente según la plataforma
265
+ function getClientScript(pageFile, platform) {
266
+ const rel = pageFile.replace(/^app\/pages\//, '').replace(/\.tsx$|\.jsx$/, '');
267
+ if (!isProduction) {
268
+ // En dev, intentar cargar el entry-client específico de la plataforma
269
+ if (platform === 'mobile') {
270
+ return `/dist/.entries/${rel}__entry-client.mobile.tsx`;
271
+ }
272
+ return `/dist/.entries/${rel}__entry-client.tsx`;
273
+ }
274
+ // En producción, buscar en el manifest el entry-client correcto
275
+ let entryKey = `dist/.entries/${rel}__entry-client.tsx`;
276
+ if (platform === 'mobile') {
277
+ const mobileKey = `dist/.entries/${rel}__entry-client.mobile.tsx`;
278
+ if (manifest[mobileKey]) {
279
+ entryKey = mobileKey;
280
+ }
281
+ }
282
+ const chunk = manifest[entryKey];
283
+ return chunk ? `/${chunk.file}` : null;
284
+ }
285
+ // Función para obtener CSS del cliente (restaurado para producción)
286
+ function getClientCss(pageFile, platform) {
287
+ if (!isProduction || !pageFile) {
288
+ return ''; // En dev, Vite maneja los estilos automáticamente vía HMR
289
+ }
290
+ // En producción, el CSS se incluye en el entry-client correspondiente
291
+ const rel = pageFile.replace(/^app\/pages\//, '').replace(/\.tsx$|\.jsx$/, '');
292
+ // Determinar qué entry-client usar según la plataforma
293
+ let entryKey = `dist/.entries/${rel}__entry-client.tsx`;
294
+ if (platform === 'mobile') {
295
+ const mobileKey = `dist/.entries/${rel}__entry-client.mobile.tsx`;
296
+ if (manifest[mobileKey]) {
297
+ entryKey = mobileKey;
298
+ }
299
+ }
300
+ const entryChunk = manifest[entryKey];
301
+ if (entryChunk && entryChunk.css) {
302
+ return entryChunk.css.map((cssFile) => `<link rel="stylesheet" href="/${cssFile}">`).join('');
303
+ }
304
+ return '';
305
+ }
306
+ // Generar HTML completo
307
+ const scriptSrc = getClientScript(page.file, platform);
308
+ const scriptTag = scriptSrc ? `<script type="module" src="${scriptSrc}"></script>` : '';
309
+ const cssLinks = page?.file ? getClientCss(page.file, platform) : '';
310
+ const html = template
311
+ .replace('<!--app-head-->', cssLinks)
312
+ .replace('<!--app-html-->', rendered.html)
313
+ .replace('</body>', `<script>
314
+ window.__INITIAL_PROPS__=${JSON.stringify(rendered.props || {})};
315
+ window.__PAGE_ROUTE__=${JSON.stringify(page.route)};
316
+ window.__PAGE_FILE__=${JSON.stringify(page.file)};
317
+ </script>
318
+ ${scriptTag}
319
+ </body>`);
320
+ // Inyectar platform class si no es desktop
321
+ return platform !== 'desktop'
322
+ ? html.replace('<html', `<html class="${platform}"`)
323
+ : html;
324
+ }
325
+ /**
326
+ * Detecta platform desde el User-Agent
327
+ */
328
+ export function detectPlatform(userAgent) {
329
+ const ua = userAgent.toLowerCase();
330
+ const mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone'];
331
+ return mobileKeywords.some(keyword => ua.includes(keyword)) ? 'mobile' : 'desktop';
332
+ }
333
+ /**
334
+ * Helper para listar páginas detectadas
335
+ */
336
+ export function listDetectedPages() {
337
+ return getPages();
338
+ }
339
+ // Re-export del core para conveniencia
340
+ export { getPages } from '@ressjs/core';
341
+ //# sourceMappingURL=simple-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-router.js","sourceRoot":"","sources":["../src/simple-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAChF,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,OAAO,MAAM,SAAS,CAAA;AAiB7B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,UAAiC,EAAE;IAC5E,MAAM,EACJ,IAAI,GAAG,IAAI,EACX,IAAI,GAAG,GAAG,EACV,uBAAuB,GAAG,IAAI,EAC/B,GAAG,OAAO,CAAA;IAEX,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;IAC1D,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;IAErB,IAAI,IAAS,CAAA;IACb,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,IAAI,YAAY,GAAG,EAAE,CAAA;IAErB,mCAAmC;IACnC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;QAChE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;QAC7C,IAAI,GAAG,MAAM,YAAY,CAAC;YACxB,MAAM,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;YAChC,OAAO,EAAE,QAAQ;YACjB,IAAI;SACL,CAAC,CAAA;QACF,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAEzB,sFAAsF;QACtF,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAA;QAE1D,4BAA4B;QAC5B,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,EAAE,OAAO,CAAC,CAAC,CAAA;QACxF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAA;YACxE,QAAQ,GAAG,EAAE,CAAA;QACf,CAAC;QAED,kCAAkC;QAClC,MAAM,mBAAmB,EAAE,CAAA;IAE7B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAA;QAC/D,MAAM,WAAW,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAA;QACzD,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;QAE3C,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;QACtB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAExD,8BAA8B;QAC9B,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,EAAE,OAAO,CAAC,CAAC,CAAA;QACtF,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;IAC3D,CAAC;IAED,iDAAiD;IACjD,MAAM,UAAU,GAAG,gBAAgB,CAAC;QAClC,uBAAuB;QACvB,IAAI;QACJ,QAAQ;QACR,YAAY;QACZ,YAAY;KACb,CAAC,CAAA;IAEF,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;IACxB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEjC,mCAAmC;IACnC,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;YACxB,OAAO,CAAC,GAAG,CAAC,mDAAmD,IAAI,EAAE,CAAC,CAAA;YACtE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;YACvC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACnB,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;YACjD,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA6B,EAAE;IAC9D,+DAA+D;IAC/D,MAAM,eAAe,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,YAAY,CAAA;IAEnF,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAC/C,OAAO,0BAA0B,CAAC,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED,8CAA8C;IAC9C,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAA;AACpC,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CAAC,OAA0B;IAC5D,MAAM,EACJ,uBAAuB,GAAG,IAAI,EAC9B,cAAc,EACf,GAAG,OAAO,CAAA;IAEX,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;IAE1D,IAAI,IAAS,CAAA;IACb,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,IAAI,YAAY,GAAG,EAAE,CAAA;IACrB,IAAI,YAAY,GAAQ,IAAI,CAAA;IAC5B,IAAI,WAAW,GAAG,KAAK,CAAA;IAEvB,yCAAyC;IACzC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAA;IAE3B,wCAAwC;IACxC,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE;QACpC,IAAI,WAAW;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;QAExD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAA;YAC1D,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;YAC7C,IAAI,GAAG,MAAM,YAAY,CAAC;gBACxB,MAAM,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;gBAChC,OAAO,EAAE,QAAQ;gBACjB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG;aAC9B,CAAC,CAAA;YAEF,8CAA8C;YAC9C,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAEhC,4BAA4B;YAC5B,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,EAAE,OAAO,CAAC,CAAC,CAAA;YACxF,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;gBACpE,QAAQ,GAAG,EAAE,CAAA;YACf,CAAC;YAED,kCAAkC;YAClC,MAAM,mBAAmB,EAAE,CAAA;QAE7B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;YAEzD,sCAAsC;YACtC,MAAM,WAAW,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAA;YACzD,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;YAE3C,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;YAC7B,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAEzD,8BAA8B;YAC9B,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,EAAE,OAAO,CAAC,CAAC,CAAA;YACtF,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;QAC3D,CAAC;QAED,WAAW,GAAG,IAAI,CAAA;QAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;IACzC,CAAC,CAAA;IAED,6BAA6B;IAC7B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,OAAO,CAAC,GAAG,CAAC,oDAAoD,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAA;IAErF,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAEhE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAClD,IAAI,CAAC;gBACH,oDAAoD;gBACpD,MAAM,kBAAkB,EAAE,CAAA;gBAE1B,oBAAoB;gBACpB,IAAI,QAAQ,GAAG,SAAS,CAAA;gBACxB,IAAI,uBAAuB,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;oBAChE,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC;yBACpF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;oBAC/C,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC5C,CAAC;gBAED,iDAAiD;gBACjD,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAA;oBAClE,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;oBAC1C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACd,OAAM;gBACR,CAAC;gBAED,kCAAkC;gBAClC,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;oBAC1C,YAAY,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAA;gBAClD,CAAC;gBAED,aAAa;gBACb,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;gBACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;gBAChC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAA;gBAEtD,mBAAmB;gBACnB,IAAI,QAAQ,CAAA;gBACZ,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;oBACrD,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;gBAC7D,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,YAAY,CAAA;gBACzB,CAAC;gBAED,wBAAwB;gBACxB,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;gBAEzF,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;gBAC1C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAEhB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAA;gBAC/D,IAAI,IAAI,EAAE,gBAAgB,EAAE,CAAC;oBAC3B,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;gBAC9B,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,OAA0B;IACpD,MAAM,EACJ,uBAAuB,GAAG,IAAI,EAC9B,IAAI,EACJ,QAAQ,GAAG,EAAE,EACb,YAAY,GAAG,EAAE,EACjB,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EACpD,cAAc,EACf,GAAG,OAAO,CAAA;IAEX,MAAM,MAAM,GAAG,MAAM,EAAE,CAAA;IACvB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,IAAI,YAAY,GAAQ,IAAI,CAAA;IAE5B,OAAO,CAAC,GAAG,CAAC,oCAAoC,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAA;IAErE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAEhE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC9C,IAAI,CAAC;gBACH,oBAAoB;gBACpB,IAAI,QAAQ,GAAG,SAAS,CAAA;gBACxB,IAAI,uBAAuB,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;oBAChE,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC;yBACpF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;oBAC/C,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC5C,CAAC;gBAED,iDAAiD;gBACjD,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAA;oBAClE,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;oBAC1C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACd,OAAM;gBACR,CAAC;gBAED,kCAAkC;gBAClC,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;oBAC1C,YAAY,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAA;gBAClD,CAAC;gBAED,aAAa;gBACb,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;gBACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;gBAChC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAA;gBAEtD,mBAAmB;gBACnB,IAAI,QAAQ,CAAA;gBACZ,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;oBACrD,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;gBAC7D,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,YAAY,CAAA;gBACzB,CAAC;gBAED,wBAAwB;gBACxB,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;gBAEzF,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;gBAC1C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAEhB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAA;gBAC/D,IAAI,IAAI,EAAE,gBAAgB,EAAE,CAAC;oBAC3B,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;gBAC9B,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,QAAgB,EAChB,QAAa,EACb,IAAS,EACT,QAAa,EACb,QAAgB,EAChB,YAAqB;IAErB,8DAA8D;IAC9D,SAAS,eAAe,CAAC,QAAgB,EAAE,QAAgB;QACzD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;QAE9E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,sEAAsE;YACtE,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,OAAO,kBAAkB,GAAG,2BAA2B,CAAA;YACzD,CAAC;YACD,OAAO,kBAAkB,GAAG,oBAAoB,CAAA;QAClD,CAAC;QAED,gEAAgE;QAChE,IAAI,QAAQ,GAAG,iBAAiB,GAAG,oBAAoB,CAAA;QACvD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,iBAAiB,GAAG,2BAA2B,CAAA;YACjE,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxB,QAAQ,GAAG,SAAS,CAAA;YACtB,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAChC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,oEAAoE;IACpE,SAAS,YAAY,CAAC,QAAgB,EAAE,QAAgB;QACtD,IAAI,CAAC,YAAY,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAA,CAAC,0DAA0D;QACtE,CAAC;QAED,sEAAsE;QACtE,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;QAE9E,uDAAuD;QACvD,IAAI,QAAQ,GAAG,iBAAiB,GAAG,oBAAoB,CAAA;QACvD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,iBAAiB,GAAG,2BAA2B,CAAA;YACjE,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxB,QAAQ,GAAG,SAAS,CAAA;YACtB,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACrC,IAAI,UAAU,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;YACjC,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAe,EAAE,EAAE,CAC5C,iCAAiC,OAAO,IAAI,CAC7C,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACZ,CAAC;QAED,OAAO,EAAE,CAAA;IACX,CAAC;IAED,wBAAwB;IACxB,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACtD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,8BAA8B,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,CAAA;IACvF,MAAM,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEpE,MAAM,IAAI,GAAG,QAAQ;SAClB,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC;SACpC,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC;SACzC,OAAO,CAAC,SAAS,EAChB;mCAC6B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;gCACvC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;+BAC3B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;;QAEhD,SAAS;cACH,CACT,CAAA;IAEH,2CAA2C;IAC3C,OAAO,QAAQ,KAAK,SAAS;QAC3B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,QAAQ,GAAG,CAAC;QACpD,CAAC,CAAC,IAAI,CAAA;AACV,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,CAAA;IAClC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC,CAAA;IAC7F,OAAO,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;AACpF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,QAAQ,EAAE,CAAA;AACnB,CAAC;AAED,uCAAuC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@ressjs/vite-router",
3
+ "version": "0.1.0",
4
+ "description": "Express router factory for ress.js with automatic page detection and SSR",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "dev": "tsc --watch",
23
+ "clean": "rm -rf dist",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "ssr",
28
+ "react",
29
+ "vite",
30
+ "express",
31
+ "router"
32
+ ],
33
+ "author": "ressjs team",
34
+ "license": "MIT",
35
+ "devDependencies": {
36
+ "@types/compression": "^1.7.5",
37
+ "@types/express": "^5.0.0",
38
+ "@types/node": "^22.13.4",
39
+ "typescript": "~5.7.3"
40
+ },
41
+ "dependencies": {
42
+ "@ressjs/core": "^0.1.0",
43
+ "chokidar": "^4.0.3",
44
+ "compression": "^1.8.0",
45
+ "express": "^5.0.1",
46
+ "sirv": "^3.0.1"
47
+ },
48
+ "peerDependencies": {
49
+ "vite": "^6.0.0"
50
+ },
51
+ "gitHead": "192e13e79f9a9ec584b4e1c51c2aa04bd81161ec"
52
+ }