slicejs-web-framework 2.4.3 → 2.4.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.
|
@@ -295,9 +295,18 @@ export default class Controller {
|
|
|
295
295
|
return Promise.resolve(false);
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
// Set tracking flags synchronously before any async work, so callers that
|
|
299
|
+
// await import() see the flags set immediately when the Promise resolves.
|
|
300
|
+
const { components, metadata } = bundle;
|
|
301
|
+
const bundleKey = metadata?.bundleKey;
|
|
302
|
+
if (bundleKey) {
|
|
303
|
+
this.loadedBundles.add(bundleKey);
|
|
304
|
+
if (metadata?.type === 'critical') {
|
|
305
|
+
this.criticalBundleLoaded = true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
299
308
|
|
|
300
|
-
|
|
309
|
+
console.log(`📦 Registering bundle: ${metadata.type} (${metadata.componentCount} components)`);
|
|
301
310
|
|
|
302
311
|
const entries = Object.entries(components);
|
|
303
312
|
const chunkSize = 50;
|
|
@@ -19,7 +19,8 @@ export default class StylesManager {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (slice.themeConfig.enabled) {
|
|
22
|
-
const ThemeManagerClass = slice.frameworkClasses?.ThemeManager
|
|
22
|
+
const ThemeManagerClass = slice.frameworkClasses?.ThemeManager
|
|
23
|
+
|| await slice.getClass(`${slice.paths.structuralComponentFolderPath}/StylesManager/ThemeManager/ThemeManager.js`);
|
|
23
24
|
if (!ThemeManagerClass) {
|
|
24
25
|
throw new Error('ThemeManager not available');
|
|
25
26
|
}
|
package/Slice/Slice.js
CHANGED
|
@@ -21,6 +21,10 @@ export default class Slice {
|
|
|
21
21
|
this.loadingConfig = sliceConfig.loading;
|
|
22
22
|
this.eventsConfig = sliceConfig.events;
|
|
23
23
|
|
|
24
|
+
// Default to production until init() resolves the actual mode.
|
|
25
|
+
// Safe to call isProduction() before init() completes.
|
|
26
|
+
this._mode = 'production';
|
|
27
|
+
|
|
24
28
|
// 📦 Bundle system is initialized automatically via import in index.js
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -39,11 +43,12 @@ export default class Slice {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
/**
|
|
42
|
-
*
|
|
46
|
+
* Returns true when running in production mode.
|
|
47
|
+
* Reliable after init() has completed.
|
|
43
48
|
* @returns {boolean}
|
|
44
49
|
*/
|
|
45
50
|
isProduction() {
|
|
46
|
-
return
|
|
51
|
+
return this._mode === 'production';
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
/**
|
|
@@ -233,7 +238,6 @@ async function loadConfig() {
|
|
|
233
238
|
const response = await fetch('/sliceConfig.json'); // 🔹 Express lo sirve desde `src/`
|
|
234
239
|
if (!response.ok) throw new Error('Error loading sliceConfig.json');
|
|
235
240
|
const json = await response.json();
|
|
236
|
-
console.log(json);
|
|
237
241
|
return json;
|
|
238
242
|
} catch (error) {
|
|
239
243
|
console.error(`Error loading config file: ${error.message}`);
|
|
@@ -250,6 +254,20 @@ async function init() {
|
|
|
250
254
|
return;
|
|
251
255
|
}
|
|
252
256
|
|
|
257
|
+
// 1. Resolve runtime mode via dev server endpoint.
|
|
258
|
+
// In production the endpoint returns 404 (not registered), so catch/non-ok is expected.
|
|
259
|
+
let envMode = null;
|
|
260
|
+
try {
|
|
261
|
+
const envRes = await fetch('/slice-env.json', { cache: 'no-store' });
|
|
262
|
+
if (envRes.ok) {
|
|
263
|
+
const env = await envRes.json();
|
|
264
|
+
envMode = env.mode; // 'development' | 'production'
|
|
265
|
+
}
|
|
266
|
+
} catch (error) {
|
|
267
|
+
// Endpoint not available — normal in production
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 2. Fetch bundle config (existing logic, unchanged)
|
|
253
271
|
let frameworkClasses = null;
|
|
254
272
|
let bundleConfigJson = null;
|
|
255
273
|
try {
|
|
@@ -261,47 +279,68 @@ async function init() {
|
|
|
261
279
|
// ignore
|
|
262
280
|
}
|
|
263
281
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
282
|
+
// 3. Determine canonical mode: env endpoint takes precedence, then bundle config
|
|
283
|
+
let resolvedMode;
|
|
284
|
+
if (envMode) {
|
|
285
|
+
resolvedMode = envMode;
|
|
286
|
+
} else if (bundleConfigJson?.production) {
|
|
287
|
+
resolvedMode = 'production';
|
|
288
|
+
} else {
|
|
289
|
+
resolvedMode = 'development';
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// 4. Load framework classes.
|
|
293
|
+
// In production the bundler generates slice-bundle.framework.js which
|
|
294
|
+
// sets window.SLICE_FRAMEWORK_CLASSES. In dev mode always use individual
|
|
295
|
+
// imports so the live /Slice/ source is served directly without bundles.
|
|
296
|
+
if (resolvedMode === 'production' && bundleConfigJson?.bundles?.framework?.file) {
|
|
297
|
+
try {
|
|
298
|
+
await import(`/bundles/${bundleConfigJson.bundles.framework.file}`);
|
|
299
|
+
if (window.SLICE_FRAMEWORK_CLASSES) {
|
|
300
|
+
frameworkClasses = window.SLICE_FRAMEWORK_CLASSES;
|
|
301
|
+
}
|
|
302
|
+
} catch (e) {
|
|
303
|
+
// framework bundle failed — fall through to individual imports
|
|
304
|
+
console.error('[Slice.js] framework bundle import failed:', e?.message || e);
|
|
305
|
+
}
|
|
271
306
|
}
|
|
272
307
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
308
|
+
if (!frameworkClasses) {
|
|
309
|
+
try {
|
|
310
|
+
const imports = await Promise.all([
|
|
311
|
+
import('./Components/Structural/Controller/Controller.js'),
|
|
312
|
+
import('./Components/Structural/StylesManager/StylesManager.js')
|
|
313
|
+
]);
|
|
314
|
+
frameworkClasses = {
|
|
315
|
+
Controller: imports[0].default,
|
|
316
|
+
StylesManager: imports[1].default
|
|
317
|
+
};
|
|
318
|
+
} catch (e) {
|
|
319
|
+
console.error('[Slice.js] individual imports fallback failed:', e?.message || e);
|
|
320
|
+
throw e;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
283
323
|
|
|
324
|
+
// 5. Create Slice instance and set resolved mode
|
|
284
325
|
window.slice = new Slice(sliceConfig, frameworkClasses);
|
|
326
|
+
window.slice._mode = resolvedMode;
|
|
285
327
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
328
|
+
// Initialize bundles before building components.
|
|
329
|
+
// Only in production — dev mode loads each component individually from source.
|
|
330
|
+
// bundleConfigJson was already fetched above (step 2); reuse it.
|
|
331
|
+
try {
|
|
332
|
+
if (resolvedMode === 'production' && bundleConfigJson) {
|
|
333
|
+
window.slice.controller.bundleConfig = bundleConfigJson;
|
|
334
|
+
}
|
|
293
335
|
|
|
294
336
|
if (window.slice.controller.bundleConfig) {
|
|
295
337
|
const config = window.slice.controller.bundleConfig;
|
|
296
338
|
|
|
297
339
|
const criticalFile = config?.bundles?.critical?.file;
|
|
298
340
|
if (criticalFile) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
window.slice.controller.loadedBundles.add('critical');
|
|
303
|
-
window.slice.controller.criticalBundleLoaded = true;
|
|
304
|
-
}
|
|
341
|
+
// Bundle auto-registers itself on import via its own registration block.
|
|
342
|
+
// No explicit registerBundle() call needed — flags are set inside registerBundle().
|
|
343
|
+
await import(`/bundles/${criticalFile}`);
|
|
305
344
|
}
|
|
306
345
|
|
|
307
346
|
const routeBundles = config?.routeBundles || {};
|
|
@@ -313,13 +352,10 @@ async function init() {
|
|
|
313
352
|
if (bundleName === 'critical') continue;
|
|
314
353
|
const bundleInfo = config?.bundles?.routes?.[bundleName];
|
|
315
354
|
if (!bundleInfo?.file) continue;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
};
|
|
355
|
+
// Bundle auto-registers itself on import.
|
|
356
|
+
await import(`/bundles/${bundleInfo.file}`);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
323
359
|
|
|
324
360
|
if (typeof requestIdleCallback === 'function') {
|
|
325
361
|
requestIdleCallback(() => loadRouteBundles());
|
package/api/index.js
CHANGED
|
@@ -86,6 +86,23 @@ app.use((req, res, next) => {
|
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
+
// ==============================================
|
|
90
|
+
// RUNTIME MODE ENDPOINT
|
|
91
|
+
// ==============================================
|
|
92
|
+
|
|
93
|
+
// Expone el modo actual al framework Slice.js en runtime.
|
|
94
|
+
// Solo se registra en development — 404 en production indica modo producción.
|
|
95
|
+
if (runMode === 'development') {
|
|
96
|
+
app.get('/slice-env.json', (req, res) => {
|
|
97
|
+
res.json({ mode: 'development' });
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
// Explicit 404 so the SPA fallback doesn't return 200 for this dev-only endpoint.
|
|
101
|
+
app.get('/slice-env.json', (req, res) => {
|
|
102
|
+
res.status(404).json({ error: 'Not found' });
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
// ==============================================
|
|
90
107
|
// ARCHIVOS ESTÁTICOS (DESPUÉS DE SEGURIDAD)
|
|
91
108
|
// ==============================================
|