slicejs-web-framework 2.2.13 → 2.3.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/README.md +155 -156
- package/Slice/Components/Structural/ContextManager/ContextManager.js +361 -0
- package/Slice/Components/Structural/Controller/Controller.js +131 -96
- package/Slice/Components/Structural/EventManager/EventManager.js +329 -0
- package/Slice/Components/Structural/Router/Router.js +112 -103
- package/Slice/Slice.js +83 -35
- package/package.json +1 -1
- package/src/Components/AppComponents/HomePage/HomePage.js +195 -195
- package/src/Components/Visual/CodeVisualizer/CodeVisualizer.js +3 -4
- package/src/Components/components.js +1 -2
- package/src/sliceConfig.json +59 -53
- package/src/Components/Service/Translator/Translator.js +0 -45
- package/src/Components/Service/Translator/messages.json +0 -58
|
@@ -54,8 +54,9 @@ export default class Controller {
|
|
|
54
54
|
|
|
55
55
|
if (!bundleInfo && this.bundleConfig?.bundles?.routes) {
|
|
56
56
|
const normalizedName = bundleName?.toLowerCase();
|
|
57
|
-
const matchedKey = Object.keys(this.bundleConfig.bundles.routes)
|
|
58
|
-
|
|
57
|
+
const matchedKey = Object.keys(this.bundleConfig.bundles.routes).find(
|
|
58
|
+
(key) => key.toLowerCase() === normalizedName
|
|
59
|
+
);
|
|
59
60
|
if (matchedKey) {
|
|
60
61
|
bundleInfo = this.bundleConfig.bundles.routes[matchedKey];
|
|
61
62
|
}
|
|
@@ -77,7 +78,6 @@ export default class Controller {
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
this.loadedBundles.add(bundleName);
|
|
80
|
-
|
|
81
81
|
} catch (error) {
|
|
82
82
|
console.warn(`Failed to load bundle ${bundleName}:`, error);
|
|
83
83
|
}
|
|
@@ -129,26 +129,37 @@ export default class Controller {
|
|
|
129
129
|
.replace(/export\s+function\s+(\w+)/g, 'window.$1 = function')
|
|
130
130
|
.replace(/export\s+default\s+/g, 'window.defaultExport =')
|
|
131
131
|
.replace(/export\s*{\s*([^}]+)\s*}/g, (match, exports) => {
|
|
132
|
-
return exports
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
return exports
|
|
133
|
+
.split(',')
|
|
134
|
+
.map((exp) => {
|
|
135
|
+
const cleanExp = exp.trim();
|
|
136
|
+
const varName = cleanExp.split(' as ')[0].trim();
|
|
137
|
+
return `window.${varName} = ${varName};`;
|
|
138
|
+
})
|
|
139
|
+
.join('\n');
|
|
137
140
|
})
|
|
138
141
|
// Remove any remaining export keywords
|
|
139
142
|
.replace(/^\s*export\s+/gm, '');
|
|
140
143
|
|
|
141
144
|
// Evaluate the dependency
|
|
142
145
|
try {
|
|
143
|
-
new Function('slice', 'customElements', 'window', 'document', processedContent)
|
|
144
|
-
|
|
146
|
+
new Function('slice', 'customElements', 'window', 'document', processedContent)(
|
|
147
|
+
window.slice,
|
|
148
|
+
window.customElements,
|
|
149
|
+
window,
|
|
150
|
+
window.document
|
|
151
|
+
);
|
|
145
152
|
} catch (evalError) {
|
|
146
153
|
console.warn(`❌ Failed to evaluate processed dependency ${depName}:`, evalError);
|
|
147
154
|
console.warn('Processed content preview:', processedContent.substring(0, 200));
|
|
148
155
|
// Try evaluating the original content as fallback
|
|
149
156
|
try {
|
|
150
|
-
new Function('slice', 'customElements', 'window', 'document', depContent)
|
|
151
|
-
|
|
157
|
+
new Function('slice', 'customElements', 'window', 'document', depContent)(
|
|
158
|
+
window.slice,
|
|
159
|
+
window.customElements,
|
|
160
|
+
window,
|
|
161
|
+
window.document
|
|
162
|
+
);
|
|
152
163
|
console.log(`✅ Fallback evaluation succeeded for ${depName}`);
|
|
153
164
|
} catch (fallbackError) {
|
|
154
165
|
console.warn(`❌ Fallback evaluation also failed for ${depName}:`, fallbackError);
|
|
@@ -169,52 +180,59 @@ export default class Controller {
|
|
|
169
180
|
for (const [componentName, componentData] of Object.entries(components)) {
|
|
170
181
|
// For JavaScript classes, we need to evaluate the code
|
|
171
182
|
if (componentData.js && !this.classes.has(componentName)) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
try {
|
|
184
|
+
// Create evaluation context with dependencies
|
|
185
|
+
let evalCode = componentData.js;
|
|
186
|
+
|
|
187
|
+
// Prepend dependencies to make them available
|
|
188
|
+
if (componentData.dependencies) {
|
|
189
|
+
const depCode = Object.entries(componentData.dependencies)
|
|
190
|
+
.map(([depName, depContent]) => {
|
|
191
|
+
// Convert ES6 exports to global assignments
|
|
192
|
+
return depContent
|
|
193
|
+
.replace(/export\s+const\s+(\w+)\s*=/g, 'window.$1 =')
|
|
194
|
+
.replace(/export\s+let\s+(\w+)\s*=/g, 'window.$1 =')
|
|
195
|
+
.replace(/export\s+function\s+(\w+)/g, 'window.$1 = function')
|
|
196
|
+
.replace(/export\s+default\s+/g, 'window.defaultExport =')
|
|
197
|
+
.replace(/export\s*{\s*([^}]+)\s*}/g, (match, exports) => {
|
|
198
|
+
return exports
|
|
199
|
+
.split(',')
|
|
200
|
+
.map((exp) => {
|
|
188
201
|
const cleanExp = exp.trim();
|
|
189
202
|
return `window.${cleanExp} = ${cleanExp};`;
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
203
|
+
})
|
|
204
|
+
.join('\n');
|
|
205
|
+
});
|
|
206
|
+
})
|
|
207
|
+
.join('\n\n');
|
|
194
208
|
|
|
195
|
-
|
|
196
|
-
|
|
209
|
+
evalCode = depCode + '\n\n' + evalCode;
|
|
210
|
+
}
|
|
197
211
|
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
// Evaluate the complete code
|
|
213
|
+
const componentClass = new Function(
|
|
214
|
+
'slice',
|
|
215
|
+
'customElements',
|
|
216
|
+
'window',
|
|
217
|
+
'document',
|
|
218
|
+
`
|
|
200
219
|
"use strict";
|
|
201
220
|
${evalCode}
|
|
202
221
|
return ${componentName};
|
|
203
|
-
`
|
|
222
|
+
`
|
|
223
|
+
)(window.slice, window.customElements, window, window.document);
|
|
204
224
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
} catch (error) {
|
|
210
|
-
console.warn(`❌ Failed to evaluate class for ${componentName}:`, error);
|
|
211
|
-
console.warn('Code that failed:', componentData.js.substring(0, 200) + '...');
|
|
225
|
+
if (componentClass) {
|
|
226
|
+
this.classes.set(componentName, componentClass);
|
|
227
|
+
console.log(`📝 Class registered for: ${componentName}`);
|
|
212
228
|
}
|
|
229
|
+
} catch (error) {
|
|
230
|
+
console.warn(`❌ Failed to evaluate class for ${componentName}:`, error);
|
|
231
|
+
console.warn('Code that failed:', componentData.js.substring(0, 200) + '...');
|
|
213
232
|
}
|
|
214
233
|
}
|
|
215
234
|
}
|
|
216
|
-
|
|
217
|
-
|
|
235
|
+
}
|
|
218
236
|
|
|
219
237
|
/**
|
|
220
238
|
* 📦 New bundle registration method (simplified and robust)
|
|
@@ -254,10 +272,13 @@ export default class Controller {
|
|
|
254
272
|
if (!processedDeps.has(depKey)) {
|
|
255
273
|
try {
|
|
256
274
|
const depContent = typeof depEntry === 'string' ? depEntry : depEntry.content;
|
|
257
|
-
const bindings = typeof depEntry === 'string' ? [] :
|
|
275
|
+
const bindings = typeof depEntry === 'string' ? [] : depEntry.bindings || [];
|
|
258
276
|
|
|
259
277
|
const fileBaseName = depKey
|
|
260
|
-
? depKey
|
|
278
|
+
? depKey
|
|
279
|
+
.split('/')
|
|
280
|
+
.pop()
|
|
281
|
+
.replace(/\.[^.]+$/, '')
|
|
261
282
|
: '';
|
|
262
283
|
const dataName = fileBaseName ? `${fileBaseName}Data` : '';
|
|
263
284
|
const exportPrefix = dataName ? `window.${dataName} = ` : '';
|
|
@@ -273,15 +294,19 @@ export default class Controller {
|
|
|
273
294
|
.replace(/window\.defaultExport\s*=\s*/g, exportPrefix || 'window.defaultExport = ')
|
|
274
295
|
// Handle export { var1, var2 } statements
|
|
275
296
|
.replace(/export\s*{\s*([^}]+)\s*}/g, (match, exportsStr) => {
|
|
276
|
-
const exports = exportsStr.split(',').map(exp => exp.trim().split(' as ')[0].trim());
|
|
277
|
-
return exports.map(varName => `window.${varName} = ${varName};`).join('\n');
|
|
297
|
+
const exports = exportsStr.split(',').map((exp) => exp.trim().split(' as ')[0].trim());
|
|
298
|
+
return exports.map((varName) => `window.${varName} = ${varName};`).join('\n');
|
|
278
299
|
})
|
|
279
300
|
// Remove any remaining export keywords
|
|
280
301
|
.replace(/^\s*export\s+/gm, '');
|
|
281
302
|
|
|
282
303
|
// Evaluate the processed content
|
|
283
|
-
new Function('slice', 'customElements', 'window', 'document', processedContent)
|
|
284
|
-
|
|
304
|
+
new Function('slice', 'customElements', 'window', 'document', processedContent)(
|
|
305
|
+
window.slice,
|
|
306
|
+
window.customElements,
|
|
307
|
+
window,
|
|
308
|
+
window.document
|
|
309
|
+
);
|
|
285
310
|
|
|
286
311
|
// Apply import bindings to map local identifiers to globals
|
|
287
312
|
for (const binding of bindings) {
|
|
@@ -289,9 +314,8 @@ export default class Controller {
|
|
|
289
314
|
|
|
290
315
|
if (binding.type === 'default') {
|
|
291
316
|
if (!window[binding.localName]) {
|
|
292
|
-
const fallbackValue =
|
|
293
|
-
? window[dataName]
|
|
294
|
-
: window.defaultExport;
|
|
317
|
+
const fallbackValue =
|
|
318
|
+
dataName && window[dataName] !== undefined ? window[dataName] : window.defaultExport;
|
|
295
319
|
if (fallbackValue !== undefined) {
|
|
296
320
|
window[binding.localName] = fallbackValue;
|
|
297
321
|
}
|
|
@@ -330,10 +354,16 @@ export default class Controller {
|
|
|
330
354
|
if (componentData.js && !this.classes.has(componentName)) {
|
|
331
355
|
try {
|
|
332
356
|
// Simple evaluation
|
|
333
|
-
const componentClass = new Function(
|
|
357
|
+
const componentClass = new Function(
|
|
358
|
+
'slice',
|
|
359
|
+
'customElements',
|
|
360
|
+
'window',
|
|
361
|
+
'document',
|
|
362
|
+
`
|
|
334
363
|
${componentData.js}
|
|
335
364
|
return ${componentName};
|
|
336
|
-
`
|
|
365
|
+
`
|
|
366
|
+
)(window.slice, window.customElements, window, window.document);
|
|
337
367
|
|
|
338
368
|
if (componentClass) {
|
|
339
369
|
this.classes.set(componentName, componentClass);
|
|
@@ -404,7 +434,7 @@ export default class Controller {
|
|
|
404
434
|
// Find component in any loaded bundle
|
|
405
435
|
const allBundles = [
|
|
406
436
|
{ name: 'critical', data: this.bundleConfig.bundles.critical },
|
|
407
|
-
...Object.entries(this.bundleConfig.bundles.routes || {}).map(([name, data]) => ({ name, data }))
|
|
437
|
+
...Object.entries(this.bundleConfig.bundles.routes || {}).map(([name, data]) => ({ name, data })),
|
|
408
438
|
];
|
|
409
439
|
|
|
410
440
|
for (const { name: bundleName, data: bundleData } of allBundles) {
|
|
@@ -479,13 +509,13 @@ export default class Controller {
|
|
|
479
509
|
*/
|
|
480
510
|
registerComponent(component, parent = null) {
|
|
481
511
|
component.parentComponent = parent;
|
|
482
|
-
|
|
512
|
+
|
|
483
513
|
// 🚀 OPTIMIZACIÓN: Precalcular y guardar profundidad
|
|
484
514
|
component._depth = parent ? (parent._depth || 0) + 1 : 0;
|
|
485
|
-
|
|
515
|
+
|
|
486
516
|
// Registrar en activeComponents
|
|
487
517
|
this.activeComponents.set(component.sliceId, component);
|
|
488
|
-
|
|
518
|
+
|
|
489
519
|
// 🚀 OPTIMIZACIÓN: Actualizar índice inverso de hijos
|
|
490
520
|
if (parent) {
|
|
491
521
|
if (!this.childrenIndex.has(parent.sliceId)) {
|
|
@@ -493,7 +523,7 @@ export default class Controller {
|
|
|
493
523
|
}
|
|
494
524
|
this.childrenIndex.get(parent.sliceId).add(component.sliceId);
|
|
495
525
|
}
|
|
496
|
-
|
|
526
|
+
|
|
497
527
|
return true;
|
|
498
528
|
}
|
|
499
529
|
|
|
@@ -549,11 +579,11 @@ export default class Controller {
|
|
|
549
579
|
if (isVisual) {
|
|
550
580
|
if (slice.paths.components[componentCategory]) {
|
|
551
581
|
path = `${baseUrl}${slice.paths.components[componentCategory].path}/${componentName}`;
|
|
552
|
-
resourceType === 'html' ? path += `/${componentName}.html` : path += `/${componentName}.css
|
|
582
|
+
resourceType === 'html' ? (path += `/${componentName}.html`) : (path += `/${componentName}.css`);
|
|
553
583
|
} else {
|
|
554
584
|
if (componentCategory === 'Structural') {
|
|
555
585
|
path = `${baseUrl}/Slice/Components/Structural/${componentName}`;
|
|
556
|
-
resourceType === 'html' ? path += `/${componentName}.html` : path += `/${componentName}.css
|
|
586
|
+
resourceType === 'html' ? (path += `/${componentName}.html`) : (path += `/${componentName}.css`);
|
|
557
587
|
} else {
|
|
558
588
|
throw new Error(`Component category '${componentCategory}' not found in paths configuration`);
|
|
559
589
|
}
|
|
@@ -612,18 +642,18 @@ export default class Controller {
|
|
|
612
642
|
|
|
613
643
|
getComponentPropsForDebugger(component) {
|
|
614
644
|
const ComponentClass = component.constructor;
|
|
615
|
-
|
|
645
|
+
|
|
616
646
|
if (ComponentClass.props) {
|
|
617
647
|
return {
|
|
618
648
|
availableProps: Object.keys(ComponentClass.props),
|
|
619
649
|
propsConfig: ComponentClass.props,
|
|
620
|
-
usedProps: this.extractUsedProps(component, ComponentClass.props)
|
|
650
|
+
usedProps: this.extractUsedProps(component, ComponentClass.props),
|
|
621
651
|
};
|
|
622
652
|
} else {
|
|
623
653
|
return {
|
|
624
654
|
availableProps: this.extractUsedProps(component),
|
|
625
655
|
propsConfig: null,
|
|
626
|
-
usedProps: this.extractUsedProps(component)
|
|
656
|
+
usedProps: this.extractUsedProps(component),
|
|
627
657
|
};
|
|
628
658
|
}
|
|
629
659
|
}
|
|
@@ -640,13 +670,13 @@ export default class Controller {
|
|
|
640
670
|
validatePropsInDevelopment(ComponentClass, providedProps, componentName) {
|
|
641
671
|
const staticProps = ComponentClass.props;
|
|
642
672
|
const usedProps = Object.keys(providedProps || {});
|
|
643
|
-
|
|
673
|
+
|
|
644
674
|
const availableProps = Object.keys(staticProps);
|
|
645
|
-
const unknownProps = usedProps.filter(prop => !availableProps.includes(prop));
|
|
646
|
-
|
|
675
|
+
const unknownProps = usedProps.filter((prop) => !availableProps.includes(prop));
|
|
676
|
+
|
|
647
677
|
if (unknownProps.length > 0) {
|
|
648
678
|
slice.logger.logWarning(
|
|
649
|
-
'PropsValidator',
|
|
679
|
+
'PropsValidator',
|
|
650
680
|
`${componentName}: Unknown props [${unknownProps.join(', ')}]. Available: [${availableProps.join(', ')}]`
|
|
651
681
|
);
|
|
652
682
|
}
|
|
@@ -654,34 +684,31 @@ export default class Controller {
|
|
|
654
684
|
const requiredProps = Object.entries(staticProps)
|
|
655
685
|
.filter(([_, config]) => config.required)
|
|
656
686
|
.map(([prop, _]) => prop);
|
|
657
|
-
|
|
658
|
-
const missingRequired = requiredProps.filter(prop => !(prop in (providedProps || {})));
|
|
687
|
+
|
|
688
|
+
const missingRequired = requiredProps.filter((prop) => !(prop in (providedProps || {})));
|
|
659
689
|
if (missingRequired.length > 0) {
|
|
660
|
-
slice.logger.logError(
|
|
661
|
-
componentName,
|
|
662
|
-
`Missing required props: [${missingRequired.join(', ')}]`
|
|
663
|
-
);
|
|
690
|
+
slice.logger.logError(componentName, `Missing required props: [${missingRequired.join(', ')}]`);
|
|
664
691
|
}
|
|
665
692
|
}
|
|
666
693
|
|
|
667
694
|
extractUsedProps(component, staticProps = null) {
|
|
668
695
|
const usedProps = {};
|
|
669
|
-
|
|
696
|
+
|
|
670
697
|
if (staticProps) {
|
|
671
|
-
Object.keys(staticProps).forEach(prop => {
|
|
698
|
+
Object.keys(staticProps).forEach((prop) => {
|
|
672
699
|
if (component[prop] !== undefined) {
|
|
673
700
|
usedProps[prop] = component[prop];
|
|
674
701
|
}
|
|
675
702
|
});
|
|
676
703
|
} else {
|
|
677
|
-
Object.getOwnPropertyNames(component).forEach(key => {
|
|
704
|
+
Object.getOwnPropertyNames(component).forEach((key) => {
|
|
678
705
|
if (key.startsWith('_') && key !== '_isActive') {
|
|
679
706
|
const propName = key.substring(1);
|
|
680
707
|
usedProps[propName] = component[propName];
|
|
681
708
|
}
|
|
682
709
|
});
|
|
683
710
|
}
|
|
684
|
-
|
|
711
|
+
|
|
685
712
|
return usedProps;
|
|
686
713
|
}
|
|
687
714
|
|
|
@@ -699,16 +726,16 @@ export default class Controller {
|
|
|
699
726
|
findAllChildComponents(parentSliceId, collected = new Set()) {
|
|
700
727
|
// 🚀 Buscar directamente en el índice: O(1)
|
|
701
728
|
const children = this.childrenIndex.get(parentSliceId);
|
|
702
|
-
|
|
729
|
+
|
|
703
730
|
if (!children) return collected;
|
|
704
|
-
|
|
731
|
+
|
|
705
732
|
// 🚀 Iterar solo los hijos directos: O(k) donde k = número de hijos
|
|
706
733
|
for (const childSliceId of children) {
|
|
707
734
|
collected.add(childSliceId);
|
|
708
735
|
// Recursión solo sobre hijos, no todos los componentes
|
|
709
736
|
this.findAllChildComponents(childSliceId, collected);
|
|
710
737
|
}
|
|
711
|
-
|
|
738
|
+
|
|
712
739
|
return collected;
|
|
713
740
|
}
|
|
714
741
|
|
|
@@ -722,8 +749,8 @@ export default class Controller {
|
|
|
722
749
|
findAllNestedComponentsInContainer(container, collected = new Set()) {
|
|
723
750
|
// Buscar todos los elementos con slice-id en el contenedor
|
|
724
751
|
const sliceComponents = container.querySelectorAll('[slice-id]');
|
|
725
|
-
|
|
726
|
-
sliceComponents.forEach(element => {
|
|
752
|
+
|
|
753
|
+
sliceComponents.forEach((element) => {
|
|
727
754
|
const sliceId = element.getAttribute('slice-id') || element.sliceId;
|
|
728
755
|
if (sliceId && this.activeComponents.has(sliceId)) {
|
|
729
756
|
collected.add(sliceId);
|
|
@@ -738,7 +765,7 @@ export default class Controller {
|
|
|
738
765
|
/**
|
|
739
766
|
* Destruye uno o múltiples componentes DE FORMA RECURSIVA
|
|
740
767
|
* 🚀 OPTIMIZADO: O(m log m) en lugar de O(n*d + m log m)
|
|
741
|
-
* @param {HTMLElement|Array<HTMLElement>|string|Array<string>} components
|
|
768
|
+
* @param {HTMLElement|Array<HTMLElement>|string|Array<string>} components
|
|
742
769
|
* @returns {number} Cantidad de componentes destruidos (incluyendo hijos)
|
|
743
770
|
*/
|
|
744
771
|
destroyComponent(components) {
|
|
@@ -763,7 +790,7 @@ export default class Controller {
|
|
|
763
790
|
}
|
|
764
791
|
|
|
765
792
|
allSliceIdsToDestroy.add(sliceId);
|
|
766
|
-
|
|
793
|
+
|
|
767
794
|
// 🚀 OPTIMIZADO: Usa childrenIndex en lugar de recorrer todos los componentes
|
|
768
795
|
this.findAllChildComponents(sliceId, allSliceIdsToDestroy);
|
|
769
796
|
}
|
|
@@ -773,9 +800,9 @@ export default class Controller {
|
|
|
773
800
|
const sortedSliceIds = Array.from(allSliceIdsToDestroy).sort((a, b) => {
|
|
774
801
|
const compA = this.activeComponents.get(a);
|
|
775
802
|
const compB = this.activeComponents.get(b);
|
|
776
|
-
|
|
803
|
+
|
|
777
804
|
if (!compA || !compB) return 0;
|
|
778
|
-
|
|
805
|
+
|
|
779
806
|
// 🚀 O(1) en lugar de O(d) - usa profundidad precalculada
|
|
780
807
|
return (compB._depth || 0) - (compA._depth || 0);
|
|
781
808
|
});
|
|
@@ -785,7 +812,7 @@ export default class Controller {
|
|
|
785
812
|
// PASO 3: Destruir en orden correcto (hijos antes que padres)
|
|
786
813
|
for (const sliceId of sortedSliceIds) {
|
|
787
814
|
const component = this.activeComponents.get(sliceId);
|
|
788
|
-
|
|
815
|
+
|
|
789
816
|
if (!component) continue;
|
|
790
817
|
|
|
791
818
|
// Ejecutar hook beforeDestroy si existe
|
|
@@ -797,9 +824,14 @@ export default class Controller {
|
|
|
797
824
|
}
|
|
798
825
|
}
|
|
799
826
|
|
|
827
|
+
// Limpiar suscripciones de eventos del componente
|
|
828
|
+
if (slice.events) {
|
|
829
|
+
slice.events.cleanupComponent(sliceId);
|
|
830
|
+
}
|
|
831
|
+
|
|
800
832
|
// 🚀 Limpiar del índice de hijos
|
|
801
833
|
this.childrenIndex.delete(sliceId);
|
|
802
|
-
|
|
834
|
+
|
|
803
835
|
// Si tiene padre, remover de la lista de hijos del padre
|
|
804
836
|
if (component.parentComponent) {
|
|
805
837
|
const parentChildren = this.childrenIndex.get(component.parentComponent.sliceId);
|
|
@@ -844,14 +876,14 @@ export default class Controller {
|
|
|
844
876
|
|
|
845
877
|
// 🚀 Recolectar componentes usando índice optimizado
|
|
846
878
|
const allSliceIds = this.findAllNestedComponentsInContainer(container);
|
|
847
|
-
|
|
879
|
+
|
|
848
880
|
if (allSliceIds.size === 0) {
|
|
849
881
|
return 0;
|
|
850
882
|
}
|
|
851
883
|
|
|
852
884
|
// Destruir usando el método principal optimizado
|
|
853
885
|
const count = this.destroyComponent(Array.from(allSliceIds));
|
|
854
|
-
|
|
886
|
+
|
|
855
887
|
if (count > 0) {
|
|
856
888
|
slice.logger.logInfo('Controller', `Destroyed ${count} component(s) from container (including nested)`);
|
|
857
889
|
}
|
|
@@ -880,9 +912,12 @@ export default class Controller {
|
|
|
880
912
|
}
|
|
881
913
|
|
|
882
914
|
const count = this.destroyComponent(componentsToDestroy);
|
|
883
|
-
|
|
915
|
+
|
|
884
916
|
if (count > 0) {
|
|
885
|
-
slice.logger.logInfo(
|
|
917
|
+
slice.logger.logInfo(
|
|
918
|
+
'Controller',
|
|
919
|
+
`Destroyed ${count} component(s) matching pattern: ${pattern} (including nested)`
|
|
920
|
+
);
|
|
886
921
|
}
|
|
887
922
|
|
|
888
923
|
return count;
|