slicejs-web-framework 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,10 @@ export default class Router {
8
8
  this._beforeEachGuard = null;
9
9
  this._afterEachGuard = null;
10
10
 
11
+ // Router state
12
+ this._started = false;
13
+ this._autoStartTimeout = null;
14
+
11
15
  // Sistema de caché optimizado
12
16
  this.routeContainersCache = new Map();
13
17
  this.lastCacheUpdate = 0;
@@ -17,9 +21,43 @@ export default class Router {
17
21
  this.setupMutationObserver();
18
22
  }
19
23
 
20
- async init() {
21
- await this.loadInitialRoute();
24
+ /**
25
+ * Inicializa el router
26
+ * Si el usuario no llama start() manualmente, se auto-inicia después de un delay
27
+ */
28
+ init() {
22
29
  window.addEventListener('popstate', this.onRouteChange.bind(this));
30
+
31
+ // Auto-start después de 50ms si el usuario no llama start() manualmente
32
+ // Esto da tiempo para que el usuario configure guards si lo necesita
33
+ this._autoStartTimeout = setTimeout(async () => {
34
+ if (!this._started) {
35
+ slice.logger.logInfo('Router', 'Auto-starting router (no manual start() called)');
36
+ await this.start();
37
+ }
38
+ }, 50);
39
+ }
40
+
41
+ /**
42
+ * Inicia el router y carga la ruta inicial
43
+ * OPCIONAL: Solo necesario si usas guards (beforeEach/afterEach)
44
+ * Si no lo llamas, el router se auto-inicia después de 50ms
45
+ */
46
+ async start() {
47
+ // Prevenir múltiples llamadas
48
+ if (this._started) {
49
+ slice.logger.logWarning('Router', 'start() already called');
50
+ return;
51
+ }
52
+
53
+ // Cancelar auto-start si existe
54
+ if (this._autoStartTimeout) {
55
+ clearTimeout(this._autoStartTimeout);
56
+ this._autoStartTimeout = null;
57
+ }
58
+
59
+ this._started = true;
60
+ await this.loadInitialRoute();
23
61
  }
24
62
 
25
63
  // ============================================
@@ -56,12 +94,13 @@ export default class Router {
56
94
  * Crea un objeto con información de ruta para los guards
57
95
  * @param {Object} route - Objeto de ruta
58
96
  * @param {Object} params - Parámetros de la ruta
97
+ * @param {String} requestedPath - Path original solicitado
59
98
  * @returns {Object} Objeto con path, component, params, query, metadata
60
99
  */
61
- _createRouteInfo(route, params = {}) {
100
+ _createRouteInfo(route, params = {}, requestedPath = null) {
62
101
  if (!route) {
63
102
  return {
64
- path: '/404',
103
+ path: requestedPath || '/404',
65
104
  component: 'NotFound',
66
105
  params: {},
67
106
  query: this._parseQueryParams(),
@@ -70,7 +109,7 @@ export default class Router {
70
109
  }
71
110
 
72
111
  return {
73
- path: route.fullPath || route.path,
112
+ path: requestedPath || route.fullPath || route.path,
74
113
  component: route.parentRoute ? route.parentRoute.component : route.component,
75
114
  params: params,
76
115
  query: this._parseQueryParams(),
@@ -161,31 +200,48 @@ export default class Router {
161
200
  // ROUTING CORE (MODIFICADO CON GUARDS)
162
201
  // ============================================
163
202
 
164
- async navigate(path) {
203
+ async navigate(path, _redirectChain = []) {
165
204
  const currentPath = window.location.pathname;
166
205
 
206
+
207
+ // Detectar loops infinitos: si ya visitamos esta ruta en la cadena de redirecciones
208
+ if (_redirectChain.includes(path)) {
209
+ slice.logger.logError(
210
+ 'Router',
211
+ `Guard redirection loop detected: ${_redirectChain.join(' → ')} → ${path}`
212
+ );
213
+ return;
214
+ }
215
+
216
+ // Límite de seguridad: máximo 10 redirecciones
217
+ if (_redirectChain.length >= 10) {
218
+ slice.logger.logError(
219
+ 'Router',
220
+ `Too many redirections: ${_redirectChain.join(' → ')} → ${path}`
221
+ );
222
+ return;
223
+ }
224
+
167
225
  // Obtener información de ruta actual
168
226
  const { route: fromRoute, params: fromParams } = this.matchRoute(currentPath);
169
- const from = this._createRouteInfo(fromRoute, fromParams);
227
+ const from = this._createRouteInfo(fromRoute, fromParams, currentPath);
170
228
 
171
229
  // Obtener información de ruta destino
172
230
  const { route: toRoute, params: toParams } = this.matchRoute(path);
173
- const to = this._createRouteInfo(toRoute, toParams);
231
+ const to = this._createRouteInfo(toRoute, toParams, path); // ← PASAR EL PATH AQUÍ
232
+
174
233
 
175
234
  // EJECUTAR BEFORE EACH GUARD
176
235
  const redirectPath = await this._executeBeforeEachGuard(to, from);
177
236
 
178
- // Si el guard redirige, navegar a la nueva ruta
237
+ // Si el guard redirige, agregar ruta actual a la cadena y navegar a la nueva ruta
179
238
  if (redirectPath) {
180
- // Evitar loops infinitos
181
- if (redirectPath === path) {
182
- slice.logger.logError('Router', `Guard redirection loop detected: ${path}`);
183
- return;
184
- }
185
- return this.navigate(redirectPath);
239
+ const newChain = [..._redirectChain, path];
240
+
241
+ return this.navigate(redirectPath, newChain);
186
242
  }
187
243
 
188
- // Continuar con la navegación normal
244
+ // No hay redirección - continuar con la navegación normal
189
245
  window.history.pushState({}, path, window.location.origin + path);
190
246
  await this._performNavigation(to, from);
191
247
  }
@@ -272,8 +328,8 @@ export default class Router {
272
328
  const { route, params } = this.matchRoute(path);
273
329
 
274
330
  // Para la carga inicial, también ejecutar guards
275
- const from = this._createRouteInfo(null, {});
276
- const to = this._createRouteInfo(route, params);
331
+ const from = this._createRouteInfo(null, {}, null);
332
+ const to = this._createRouteInfo(route, params, path); // ← PASAR EL PATH AQUÍ
277
333
 
278
334
  // EJECUTAR BEFORE EACH GUARD en carga inicial
279
335
  const redirectPath = await this._executeBeforeEachGuard(to, from);
package/Slice/Slice.js CHANGED
@@ -217,15 +217,6 @@ async function init() {
217
217
  window.slice.router = new RouterModule(routes);
218
218
  await window.slice.router.init();
219
219
 
220
-
221
- /*
222
- if (sliceConfig.translator.enabled) {
223
- const translator = await window.slice.build('Translator');
224
- window.slice.translator = translator;
225
- window.slice.logger.logInfo('Slice', 'Translator succesfuly enabled');
226
- }
227
- */
228
-
229
220
  }
230
221
 
231
222
  await init();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slicejs-web-framework",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=20"
package/src/App/index.js CHANGED
@@ -1,63 +1,23 @@
1
1
  import Slice from '/Slice/Slice.js';
2
2
 
3
- const CACHE_NAME = 'slice-cache-v1';
4
- const urlsToCache = [
5
- // Añade aquí las rutas de los archivos que deseas almacenar
6
- './Slice/Slice.js',
7
- './Slice/Components/Structural/Logger/Logger.js',
8
- './Slice/Components/Structural/Debugger/Debugger.js',
9
- './Slice/Components/Structural/Router/Router.js',
10
- './Slice/Components/Structural/Router/routes.js',
11
- './Slice/Components/Structural/Controller/Controller.js',
12
- './Slice/Components/Structural/StylesManager/StylesManager.js',
13
- './Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js',
14
- ];
15
3
 
16
- self.addEventListener('install', (event) => {
17
- event.waitUntil(
18
- caches.open(CACHE_NAME).then((cache) => {
19
- console.log('Opened cache');
20
- return cache.addAll(urlsToCache);
21
- })
22
- );
4
+ /*
5
+ slice.router.beforeEach(async (to, from, next) => {
6
+
7
+ if(to.metadata.private){
8
+ const isAuthenticated = await //fetchlogic for validation
9
+ if(!isAuthenticated){
10
+ return next({ path: '/login' });
11
+ }
12
+ return next();
13
+ }
14
+
15
+ return next();
23
16
  });
24
17
 
25
- self.addEventListener('fetch', (event) => {
26
- event.respondWith(
27
- caches.match(event.request).then((response) => {
28
- if (response) {
29
- return response;
30
- }
31
- return fetch(event.request);
32
- })
33
- );
34
- });
35
18
 
36
- self.addEventListener('activate', (event) => {
37
- const cacheWhitelist = [CACHE_NAME];
19
+ If any beforeEach or afterEach is defined, start the router after defining them
38
20
 
39
- event.waitUntil(
40
- caches.keys().then((cacheNames) => {
41
- return Promise.all(
42
- cacheNames.map((cacheName) => {
43
- if (cacheWhitelist.indexOf(cacheName) === -1) {
44
- return caches.delete(cacheName);
45
- }
46
- })
47
- );
48
- })
49
- );
50
- });
21
+ await slice.router.start();
51
22
 
52
- if ('serviceWorker' in navigator) {
53
- window.addEventListener('load', () => {
54
- navigator.serviceWorker
55
- .register('/service-worker.js')
56
- .then((registration) => {
57
- console.log('Service Worker registrado con éxito:', registration);
58
- })
59
- .catch((error) => {
60
- console.log('Error al registrar el Service Worker:', error);
61
- });
62
- });
63
- }
23
+ */