slicejs-web-framework 1.0.34 → 2.0.1

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/api/index.js CHANGED
@@ -11,89 +11,174 @@ import sliceConfig from '../src/sliceConfig.json' with { type: 'json' };
11
11
  let server;
12
12
 
13
13
  const app = express();
14
- const PORT = 3001;
15
14
 
16
- const isProduction = sliceConfig.production === true;
17
- const folderDeployed = isProduction ? 'dist' : 'src';
18
-
19
- // Servir archivos estáticos desde la carpeta 'Slice'
20
- app.use('/Slice/', express.static(path.join(__dirname, '..', 'node_modules', 'slicejs-web-framework', 'Slice')));
21
- // Servir archivos estáticos desde la carpeta 'App'
15
+ // Parsear argumentos de línea de comandos
16
+ const args = process.argv.slice(2);
17
+ let runMode = 'development'; // Default
22
18
 
19
+ // Detectar modo basado en argumentos
20
+ if (args.includes('--production') || args.includes('--prod')) {
21
+ runMode = 'production';
22
+ } else if (args.includes('--development') || args.includes('--dev')) {
23
+ runMode = 'development';
24
+ }
23
25
 
26
+ // También mantener compatibilidad con NODE_ENV como fallback
27
+ if (!args.length) {
28
+ const NODE_ENV = process.env.NODE_ENV || 'development';
29
+ runMode = NODE_ENV === 'production' ? 'production' : 'development';
30
+ }
24
31
 
32
+ // Obtener puerto desde sliceConfig.json, con fallback a process.env.PORT
33
+ const PORT = sliceConfig.server?.port || process.env.PORT || 3001;
25
34
 
35
+ // Determinar directorio a servir basado en argumentos
36
+ let folderDeployed;
37
+ if (runMode === 'production') {
38
+ folderDeployed = 'dist';
39
+ } else {
40
+ folderDeployed = 'src';
41
+ }
26
42
 
27
- app.get('/testing1', (req, res) => {
28
- res.send(` Actual route in server: __dirname: ${__dirname} __filename: ${__filename} - checking if file exists: ${path.join(__dirname, '..', 'src','App', 'index.html')}`);
43
+ console.log(`🚀 Starting Slice.js server in ${runMode} mode`);
44
+ console.log(`📁 Serving files from: /${folderDeployed}`);
45
+
46
+ // Middleware para servir archivos estáticos
47
+ app.use(express.static(path.join(__dirname, `../${folderDeployed}`)));
48
+
49
+ // Middleware para parsear JSON y formularios
50
+ app.use(express.json());
51
+ app.use(express.urlencoded({ extended: true }));
52
+
53
+ // Configurar headers de CORS
54
+ app.use((req, res, next) => {
55
+ res.header('Access-Control-Allow-Origin', '*');
56
+ res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
57
+ res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
58
+
59
+ if (req.method === 'OPTIONS') {
60
+ res.sendStatus(200);
61
+ } else {
62
+ next();
63
+ }
29
64
  });
30
65
 
31
-
32
- app.use(express.static(path.join(__dirname,'..', folderDeployed)));
33
-
34
-
35
- app.get('/testing2', (req, res) => {
36
- res.send(` Actual route in server: __dirname: ${__dirname} __filename: ${__filename} - checking if file exists: ${path.join(__dirname, '..', 'src','App', 'index.html')}`);
66
+ // Ruta de ejemplo para API
67
+ app.get('/api/status', (req, res) => {
68
+ res.json({
69
+ status: 'ok',
70
+ mode: runMode,
71
+ folder: folderDeployed,
72
+ timestamp: new Date().toISOString(),
73
+ framework: 'Slice.js',
74
+ version: '2.0.0'
75
+ });
37
76
  });
38
77
 
39
- if(isProduction){
40
-
41
- }
42
-
43
-
44
- // Ruta para servir el index.html desde la carpeta 'App'
78
+ // SPA fallback - servir index.html para rutas no encontradas
45
79
  app.get('*', (req, res) => {
46
- const filePath = path.join(__dirname, '..', 'src','App', 'index.html');
47
- res.sendFile(filePath);
80
+ const indexPath = path.join(__dirname, `../${folderDeployed}`, 'index.html');
81
+ res.sendFile(indexPath, (err) => {
82
+ if (err) {
83
+ res.status(404).send(`
84
+ <h1>404 - Page Not Found</h1>
85
+ <p>The requested file could not be found in /${folderDeployed}</p>
86
+ <p>Make sure you've run the appropriate build command:</p>
87
+ <ul>
88
+ <li>For development: Files should be in /src</li>
89
+ <li>For production: Run "npm run slice:build" first</li>
90
+ </ul>
91
+ `);
92
+ }
93
+ });
48
94
  });
49
95
 
50
96
  function startServer() {
51
- server = app.listen(PORT, () => {
52
- showMenu();
53
- });
97
+ server = app.listen(PORT, () => {
98
+ console.log(`✅ Server running at http://localhost:${PORT}`);
99
+ console.log(`📂 Mode: ${runMode} (serving from /${folderDeployed})`);
100
+
101
+ if (runMode === 'development') {
102
+ console.log('🔄 Development mode: Changes in /src will require server restart');
103
+ } else {
104
+ console.log('⚡ Production mode: Serving optimized files from /dist');
105
+ }
106
+
107
+ console.log('🛑 Press Ctrl+C to stop');
108
+ console.log('\n💡 Available commands:');
109
+ console.log(' - Development: npm run slice:dev');
110
+ console.log(' - Production: npm run slice:start');
111
+ console.log(' - Build: npm run slice:build');
112
+ });
113
+
114
+ // Siempre mostrar menú interactivo
115
+ setTimeout(showInteractiveMenu, 1000);
54
116
  }
55
117
 
56
- async function showMenu() {
57
-
58
- console.clear();
59
- console.log("\n=================================");
60
- console.log(" SLICE SERVER MENU ");
61
- console.log("=================================\n");
62
-
63
- const url = `http://localhost:${PORT}`;
64
- console.log(`Server is running on port ${PORT}, ${url}\n`);
65
-
66
- while (true) {
118
+ async function showInteractiveMenu() {
119
+ while (true) {
120
+ try {
121
+ console.log('\n' + '='.repeat(50));
122
+
67
123
  const { action } = await inquirer.prompt([
68
- {
69
- type: 'list',
70
- name: 'action',
71
- message: 'Select an option:',
72
- choices: ['Restart Server', 'Stop Server (Exit)']
73
- }
124
+ {
125
+ type: 'list',
126
+ name: 'action',
127
+ message: '🎛️ Server Control Menu',
128
+ choices: [
129
+ '📊 Server Status',
130
+ '🌐 Open in Browser',
131
+ '🔄 Restart Server',
132
+ '🛑 Stop Server'
133
+ ]
134
+ }
74
135
  ]);
75
-
76
- if (action === 'Stop Server (Exit)') {
77
- console.log('\nShutting down server...');
78
- server.close(() => {
79
- console.log('Server stopped.');
80
- process.exit(0);
81
- });
82
- break;
83
- } else if (action === 'Restart Server') {
84
- console.log('\nRestarting server...');
85
- server.close(() => {
86
- console.log('Server stopped. Restarting...');
87
- startServer();
88
- });
89
- break;
136
+
137
+ if (action === '📊 Server Status') {
138
+ console.log(`\n📈 Server Status:`);
139
+ console.log(` 🔗 URL: http://localhost:${PORT}`);
140
+ console.log(` 📁 Mode: ${runMode}`);
141
+ console.log(` 📂 Serving: /${folderDeployed}`);
142
+ console.log(` ⏰ Uptime: ${Math.floor(process.uptime())}s`);
143
+ } else if (action === '🌐 Open in Browser') {
144
+ const { default: open } = await import('open');
145
+ await open(`http://localhost:${PORT}`);
146
+ console.log('🌐 Opening browser...');
147
+ } else if (action === '🛑 Stop Server') {
148
+ console.log('\n🛑 Stopping server...');
149
+ server.close(() => {
150
+ console.log('✅ Server stopped successfully');
151
+ process.exit(0);
152
+ });
153
+ break;
154
+ } else if (action === '🔄 Restart Server') {
155
+ console.log('\nRestarting server...');
156
+ server.close(() => {
157
+ console.log('Server stopped. Restarting...');
158
+ startServer();
159
+ });
160
+ break;
90
161
  }
91
- }
162
+ } catch (error) {
163
+ // Si hay error con inquirer, continuar sin menú
164
+ console.log('\n💡 Interactive menu not available - Press Ctrl+C to stop');
165
+ break;
166
+ }
167
+ }
92
168
  }
93
169
 
94
- startServer();
95
-
170
+ // Manejar cierre del proceso
171
+ process.on('SIGINT', () => {
172
+ console.log('\n🛑 Slice server stopped');
173
+ process.exit(0);
174
+ });
96
175
 
97
- export default app;
176
+ process.on('SIGTERM', () => {
177
+ console.log('\n🛑 Server terminated');
178
+ process.exit(0);
179
+ });
98
180
 
181
+ // Iniciar servidor
182
+ startServer();
99
183
 
184
+ export default app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slicejs-web-framework",
3
- "version": "1.0.34",
3
+ "version": "2.0.1",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -1,196 +1,196 @@
1
- export default class HomePage extends HTMLElement {
2
- constructor(props) {
3
- super();
4
- slice.attachTemplate(this);
5
-
6
- this.$examplesContainer = this.querySelector('.examples-container');
7
-
8
- slice.controller.setComponentProps(this, props);
9
- this.debuggerProps = [];
10
- }
11
-
12
- async init() {
13
- // Crear la barra de navegación
14
- const navbar = await slice.build('Navbar', {
15
- position: 'fixed',
16
- logo: {
17
- src: '/images/Slice.js-logo.png',
18
- path: '/',
19
- },
20
- items: [
21
- { text: 'Home', path: '/' },
22
- { text: 'Playground', path: '/Playground' },
23
-
24
- ],
25
- buttons: [
26
- {
27
- value: 'Change Theme',
28
- onClickCallback: async () => {
29
- const currentTheme = slice.stylesManager.themeManager.currentTheme;
30
- if (currentTheme === 'Slice') {
31
- await slice.setTheme('Light');
32
- } else if (currentTheme === 'Light') {
33
- await slice.setTheme('Dark');
34
- } else {
35
- await slice.setTheme('Slice');
36
- }
37
- },
38
- },
39
- ],
40
- });
41
-
42
- // Crear botones para la sección de llamada a la acción
43
- const docsButton = await slice.build('Button', {
44
- value: 'Documentation',
45
- onClickCallback: () => //redirect to https://slice-js-docs.vercel.app/Documentation
46
- window.open('https://slice-js-docs.vercel.app/Documentation', '_blank'),
47
- customColor: {
48
- button: 'var(--primary-color)',
49
- label: 'var(--primary-color-contrast)'
50
- }
51
- });
52
-
53
- const componentsButton = await slice.build('Button', {
54
- value: 'Components Library',
55
- onClickCallback: () => window.open('https://slice-js-docs.vercel.app/Documentation/Visual', '_blank'),
56
- customColor: {
57
- button: 'var(--secondary-color)',
58
- label: 'var(--secondary-color-contrast)'
59
- }
60
- });
61
-
62
- // Añadir botones a la sección CTA
63
- this.querySelector('.cta-buttons').appendChild(docsButton);
64
- this.querySelector('.cta-buttons').appendChild(componentsButton);
65
-
66
- // Crear features section con un enfoque diferente (sin usar Cards)
67
- await this.createFeatures();
68
-
69
- // Crear ejemplos de componentes
70
- await this.createComponentExamples();
71
-
72
- // Configurar la sección de código de inicio
73
- await this.setupGettingStartedSection();
74
-
75
- // Añadir la barra de navegación al inicio del componente
76
- this.insertBefore(navbar, this.firstChild);
77
- }
78
-
79
- async createFeatures() {
80
- // Definir características
81
- const features = [
82
- {
83
- title: 'Component-Based',
84
- description: 'Build your app using modular, reusable components following web standards.'
85
- },
86
- {
87
- title: 'Zero Dependencies',
88
- description: 'Built with vanilla JavaScript. No external libraries required.'
89
- },
90
- {
91
- title: 'Easy Routing',
92
- description: 'Simple and powerful routing system for single page applications.'
93
- },
94
- {
95
- title: 'Theme System',
96
- description: 'Built-in theme support with easy customization through CSS variables.'
97
- },
98
- {
99
- title: 'Developer Tools',
100
- description: 'Integrated debugging and logging for faster development.'
101
- },
102
- {
103
- title: 'Performance Focused',
104
- description: 'Lightweight and optimized for fast loading and execution.'
105
- }
106
- ];
107
-
108
- const featureGrid = this.querySelector('.feature-grid');
109
-
110
- // Crear y añadir cada feature como un elemento HTML simple
111
- for (const feature of features) {
112
- const featureElement = document.createElement('div');
113
- featureElement.classList.add('feature-item');
114
-
115
- const featureTitle = document.createElement('h3');
116
- featureTitle.textContent = feature.title;
117
- featureTitle.classList.add('feature-title');
118
-
119
- const featureDescription = document.createElement('p');
120
- featureDescription.textContent = feature.description;
121
- featureDescription.classList.add('feature-description');
122
-
123
- featureElement.appendChild(featureTitle);
124
- featureElement.appendChild(featureDescription);
125
-
126
- featureGrid.appendChild(featureElement);
127
- }
128
- }
129
-
130
- async createComponentExamples() {
131
- // Crear ejemplos para demostrar componentes
132
- const inputExample = await slice.build('Input', {
133
- placeholder: 'Try typing here...',
134
- type: 'text'
135
- });
136
-
137
- const switchExample = await slice.build('Switch', {
138
- label: 'Toggle me',
139
- checked: true
140
- });
141
-
142
- const checkboxExample = await slice.build('Checkbox', {
143
- label: 'Check me',
144
- labelPlacement: 'right'
145
- });
146
-
147
- const detailsExample = await slice.build('Details', {
148
- title: 'Click to expand',
149
- text: 'This is a collapsible details component that can contain any content.'
150
- });
151
-
152
- // Crear sección para cada ejemplo
153
- const exampleSections = [
154
- { title: 'Input Component', component: inputExample },
155
- { title: 'Switch Component', component: switchExample },
156
- { title: 'Checkbox Component', component: checkboxExample },
157
- { title: 'Details Component', component: detailsExample }
158
- ];
159
-
160
- // Añadir cada ejemplo a la sección de ejemplos
161
- for (const section of exampleSections) {
162
- const container = document.createElement('div');
163
- container.classList.add('example-item');
164
-
165
- const title = document.createElement('h3');
166
- title.textContent = section.title;
167
-
168
- container.appendChild(title);
169
- container.appendChild(section.component);
170
-
171
- this.$examplesContainer.appendChild(container);
172
- }
173
- }
174
-
175
- async setupGettingStartedSection() {
176
- // Opcionalmente podríamos mejorar esta sección usando el CodeVisualizer component
177
- // en lugar del código HTML estático en el template
178
- const codeVisualizer = await slice.build('CodeVisualizer', {
179
- value: `// Initialize a new Slice.js project
180
- npm run slice:init
181
-
182
- // Create a new component
183
- npm run slice:create
184
-
185
- // Start your application
186
- npm run slice:start`,
187
- language: 'bash'
188
- });
189
-
190
- const codeSample = this.querySelector('.code-sample');
191
- codeSample.innerHTML = ''; // Clear the static code sample
192
- codeSample.appendChild(codeVisualizer);
193
- }
194
- }
195
-
1
+ export default class HomePage extends HTMLElement {
2
+ constructor(props) {
3
+ super();
4
+ slice.attachTemplate(this);
5
+
6
+ this.$examplesContainer = this.querySelector('.examples-container');
7
+
8
+ slice.controller.setComponentProps(this, props);
9
+ this.debuggerProps = [];
10
+ }
11
+
12
+ async init() {
13
+ // Crear la barra de navegación
14
+ const navbar = await slice.build('Navbar', {
15
+ position: 'fixed',
16
+ logo: {
17
+ src: '/images/Slice.js-logo.png',
18
+ path: '/',
19
+ },
20
+ items: [
21
+ { text: 'Home', path: '/' },
22
+ { text: 'Playground', path: '/Playground' },
23
+
24
+ ],
25
+ buttons: [
26
+ {
27
+ value: 'Change Theme',
28
+ onClickCallback: async () => {
29
+ const currentTheme = slice.stylesManager.themeManager.currentTheme;
30
+ if (currentTheme === 'Slice') {
31
+ await slice.setTheme('Light');
32
+ } else if (currentTheme === 'Light') {
33
+ await slice.setTheme('Dark');
34
+ } else {
35
+ await slice.setTheme('Slice');
36
+ }
37
+ },
38
+ },
39
+ ],
40
+ });
41
+
42
+ // Crear botones para la sección de llamada a la acción
43
+ const docsButton = await slice.build('Button', {
44
+ value: 'Documentation',
45
+ onClickCallback: () => //redirect to https://slice-js-docs.vercel.app/Documentation
46
+ window.open('https://slice-js-docs.vercel.app/Documentation', '_blank'),
47
+ customColor: {
48
+ button: 'var(--primary-color)',
49
+ label: 'var(--primary-color-contrast)'
50
+ }
51
+ });
52
+
53
+ const componentsButton = await slice.build('Button', {
54
+ value: 'Components Library',
55
+ onClickCallback: () => window.open('https://slice-js-docs.vercel.app/Documentation/Visual', '_blank'),
56
+ customColor: {
57
+ button: 'var(--secondary-color)',
58
+ label: 'var(--secondary-color-contrast)'
59
+ }
60
+ });
61
+
62
+ // Añadir botones a la sección CTA
63
+ this.querySelector('.cta-buttons').appendChild(docsButton);
64
+ this.querySelector('.cta-buttons').appendChild(componentsButton);
65
+
66
+ // Crear features section con un enfoque diferente (sin usar Cards)
67
+ await this.createFeatures();
68
+
69
+ // Crear ejemplos de componentes
70
+ await this.createComponentExamples();
71
+
72
+ // Configurar la sección de código de inicio
73
+ await this.setupGettingStartedSection();
74
+
75
+ // Añadir la barra de navegación al inicio del componente
76
+ this.insertBefore(navbar, this.firstChild);
77
+ }
78
+
79
+ async createFeatures() {
80
+ // Definir características
81
+ const features = [
82
+ {
83
+ title: 'Component-Based',
84
+ description: 'Build your app using modular, reusable components following web standards.'
85
+ },
86
+ {
87
+ title: 'Zero Dependencies',
88
+ description: 'Built with vanilla JavaScript. No external libraries required.'
89
+ },
90
+ {
91
+ title: 'Easy Routing',
92
+ description: 'Simple and powerful routing system for single page applications.'
93
+ },
94
+ {
95
+ title: 'Theme System',
96
+ description: 'Built-in theme support with easy customization through CSS variables.'
97
+ },
98
+ {
99
+ title: 'Developer Tools',
100
+ description: 'Integrated debugging and logging for faster development.'
101
+ },
102
+ {
103
+ title: 'Performance Focused',
104
+ description: 'Lightweight and optimized for fast loading and execution.'
105
+ }
106
+ ];
107
+
108
+ const featureGrid = this.querySelector('.feature-grid');
109
+
110
+ // Crear y añadir cada feature como un elemento HTML simple
111
+ for (const feature of features) {
112
+ const featureElement = document.createElement('div');
113
+ featureElement.classList.add('feature-item');
114
+
115
+ const featureTitle = document.createElement('h3');
116
+ featureTitle.textContent = feature.title;
117
+ featureTitle.classList.add('feature-title');
118
+
119
+ const featureDescription = document.createElement('p');
120
+ featureDescription.textContent = feature.description;
121
+ featureDescription.classList.add('feature-description');
122
+
123
+ featureElement.appendChild(featureTitle);
124
+ featureElement.appendChild(featureDescription);
125
+
126
+ featureGrid.appendChild(featureElement);
127
+ }
128
+ }
129
+
130
+ async createComponentExamples() {
131
+ // Crear ejemplos para demostrar componentes
132
+ const inputExample = await slice.build('Input', {
133
+ placeholder: 'Try typing here...',
134
+ type: 'text'
135
+ });
136
+
137
+ const switchExample = await slice.build('Switch', {
138
+ label: 'Toggle me',
139
+ checked: true
140
+ });
141
+
142
+ const checkboxExample = await slice.build('Checkbox', {
143
+ label: 'Check me',
144
+ labelPlacement: 'right'
145
+ });
146
+
147
+ const detailsExample = await slice.build('Details', {
148
+ title: 'Click to expand',
149
+ text: 'This is a collapsible details component that can contain any content.'
150
+ });
151
+
152
+ // Crear sección para cada ejemplo
153
+ const exampleSections = [
154
+ { title: 'Input Component', component: inputExample },
155
+ { title: 'Switch Component', component: switchExample },
156
+ { title: 'Checkbox Component', component: checkboxExample },
157
+ { title: 'Details Component', component: detailsExample }
158
+ ];
159
+
160
+ // Añadir cada ejemplo a la sección de ejemplos
161
+ for (const section of exampleSections) {
162
+ const container = document.createElement('div');
163
+ container.classList.add('example-item');
164
+
165
+ const title = document.createElement('h3');
166
+ title.textContent = section.title;
167
+
168
+ container.appendChild(title);
169
+ container.appendChild(section.component);
170
+
171
+ this.$examplesContainer.appendChild(container);
172
+ }
173
+ }
174
+
175
+ async setupGettingStartedSection() {
176
+ // Opcionalmente podríamos mejorar esta sección usando el CodeVisualizer component
177
+ // en lugar del código HTML estático en el template
178
+ const codeVisualizer = await slice.build('CodeVisualizer', {
179
+ value: `// Initialize a new Slice.js project
180
+ npm run slice:init
181
+
182
+ // Create a new component
183
+ npm run slice:create
184
+
185
+ // Start your application
186
+ npm run slice:start`,
187
+ language: 'bash'
188
+ });
189
+
190
+ const codeSample = this.querySelector('.code-sample');
191
+ codeSample.innerHTML = ''; // Clear the static code sample
192
+ codeSample.appendChild(codeVisualizer);
193
+ }
194
+ }
195
+
196
196
  customElements.define('slice-home-page', HomePage);