wu-framework 1.1.6 β 1.1.8
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 +511 -977
- package/dist/wu-framework.cjs.js +3 -1
- package/dist/wu-framework.cjs.js.map +1 -0
- package/dist/wu-framework.dev.js +7533 -2761
- package/dist/wu-framework.dev.js.map +1 -1
- package/dist/wu-framework.esm.js +3 -0
- package/dist/wu-framework.esm.js.map +1 -0
- package/dist/wu-framework.umd.js +3 -1
- package/dist/wu-framework.umd.js.map +1 -0
- package/integrations/astro/README.md +127 -0
- package/integrations/astro/WuApp.astro +63 -0
- package/integrations/astro/WuShell.astro +39 -0
- package/integrations/astro/index.js +68 -0
- package/integrations/astro/package.json +38 -0
- package/integrations/astro/types.d.ts +53 -0
- package/package.json +94 -74
- package/src/adapters/angular/ai.js +30 -0
- package/src/adapters/angular/index.d.ts +154 -0
- package/src/adapters/angular/index.js +932 -0
- package/src/adapters/angular.d.ts +3 -154
- package/src/adapters/angular.js +3 -813
- package/src/adapters/index.js +35 -24
- package/src/adapters/lit/ai.js +20 -0
- package/src/adapters/lit/index.d.ts +120 -0
- package/src/adapters/lit/index.js +721 -0
- package/src/adapters/lit.d.ts +3 -120
- package/src/adapters/lit.js +3 -726
- package/src/adapters/preact/ai.js +33 -0
- package/src/adapters/preact/index.d.ts +108 -0
- package/src/adapters/preact/index.js +661 -0
- package/src/adapters/preact.d.ts +3 -108
- package/src/adapters/preact.js +3 -665
- package/src/adapters/react/ai.js +135 -0
- package/src/adapters/react/index.d.ts +246 -0
- package/src/adapters/react/index.js +689 -0
- package/src/adapters/react.d.ts +3 -212
- package/src/adapters/react.js +3 -513
- package/src/adapters/shared.js +64 -0
- package/src/adapters/solid/ai.js +32 -0
- package/src/adapters/solid/index.d.ts +101 -0
- package/src/adapters/solid/index.js +586 -0
- package/src/adapters/solid.d.ts +3 -101
- package/src/adapters/solid.js +3 -591
- package/src/adapters/svelte/ai.js +31 -0
- package/src/adapters/svelte/index.d.ts +166 -0
- package/src/adapters/svelte/index.js +798 -0
- package/src/adapters/svelte.d.ts +3 -166
- package/src/adapters/svelte.js +3 -803
- package/src/adapters/vanilla/ai.js +30 -0
- package/src/adapters/vanilla/index.d.ts +179 -0
- package/src/adapters/vanilla/index.js +785 -0
- package/src/adapters/vanilla.d.ts +3 -179
- package/src/adapters/vanilla.js +3 -791
- package/src/adapters/vue/ai.js +52 -0
- package/src/adapters/vue/index.d.ts +299 -0
- package/src/adapters/vue/index.js +608 -0
- package/src/adapters/vue.d.ts +3 -299
- package/src/adapters/vue.js +3 -611
- package/src/ai/wu-ai-actions.js +261 -0
- package/src/ai/wu-ai-browser.js +663 -0
- package/src/ai/wu-ai-context.js +332 -0
- package/src/ai/wu-ai-conversation.js +554 -0
- package/src/ai/wu-ai-permissions.js +381 -0
- package/src/ai/wu-ai-provider.js +605 -0
- package/src/ai/wu-ai-schema.js +225 -0
- package/src/ai/wu-ai-triggers.js +396 -0
- package/src/ai/wu-ai.js +474 -0
- package/src/core/wu-app.js +50 -8
- package/src/core/wu-cache.js +1 -1
- package/src/core/wu-core.js +645 -677
- package/src/core/wu-html-parser.js +121 -211
- package/src/core/wu-iframe-sandbox.js +328 -0
- package/src/core/wu-mcp-bridge.js +647 -0
- package/src/core/wu-overrides.js +510 -0
- package/src/core/wu-prefetch.js +414 -0
- package/src/core/wu-proxy-sandbox.js +398 -75
- package/src/core/wu-sandbox.js +86 -268
- package/src/core/wu-script-executor.js +79 -182
- package/src/core/wu-snapshot-sandbox.js +149 -106
- package/src/core/wu-strategies.js +13 -0
- package/src/core/wu-style-bridge.js +0 -2
- package/src/index.js +139 -665
- package/dist/wu-framework.hex.js +0 -23
- package/dist/wu-framework.min.js +0 -1
- package/dist/wu-framework.obf.js +0 -1
- package/scripts/build-protected.js +0 -366
- package/scripts/build.js +0 -212
- package/scripts/rollup-plugin-hex.js +0 -143
- package/src/core/wu-registry.js +0 -60
- package/src/core/wu-sandbox-pool.js +0 -390
package/src/core/wu-sandbox.js
CHANGED
|
@@ -7,23 +7,19 @@
|
|
|
7
7
|
import { WuStyleBridge } from './wu-style-bridge.js';
|
|
8
8
|
import { WuProxySandbox } from './wu-proxy-sandbox.js';
|
|
9
9
|
import { WuSnapshotSandbox } from './wu-snapshot-sandbox.js';
|
|
10
|
-
import {
|
|
11
|
-
import { WuHtmlParser } from './wu-html-parser.js';
|
|
10
|
+
import { logger } from './wu-logger.js';
|
|
12
11
|
|
|
13
12
|
export class WuSandbox {
|
|
14
13
|
constructor() {
|
|
15
14
|
// Registros existentes
|
|
16
15
|
this.sandboxes = new Map();
|
|
17
|
-
this.globalState = new Map();
|
|
18
16
|
this.styleBridge = new WuStyleBridge();
|
|
19
17
|
|
|
20
18
|
// π NUEVOS SISTEMAS INTEGRADOS
|
|
21
19
|
this.jsSandboxes = new Map(); // ProxySandbox o SnapshotSandbox por app
|
|
22
|
-
this.scriptExecutor = new WuScriptExecutor();
|
|
23
|
-
this.htmlParser = new WuHtmlParser();
|
|
24
20
|
this.sandboxStrategy = this.detectSandboxStrategy();
|
|
25
21
|
|
|
26
|
-
|
|
22
|
+
logger.wuDebug(`Advanced isolation system initialized (strategy: ${this.sandboxStrategy})`);
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
/**
|
|
@@ -40,15 +36,15 @@ export class WuSandbox {
|
|
|
40
36
|
});
|
|
41
37
|
testProxy.test = 'value';
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
logger.wuDebug('Proxy available - using ProxySandbox strategy');
|
|
44
40
|
return 'proxy';
|
|
45
41
|
} catch (error) {
|
|
46
|
-
|
|
42
|
+
logger.wuWarn('Proxy not working - falling back to SnapshotSandbox');
|
|
47
43
|
return 'snapshot';
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
logger.wuWarn('Proxy not available - using SnapshotSandbox strategy');
|
|
52
48
|
return 'snapshot';
|
|
53
49
|
}
|
|
54
50
|
|
|
@@ -60,7 +56,7 @@ export class WuSandbox {
|
|
|
60
56
|
* @returns {Object} Sandbox con shadow root y container
|
|
61
57
|
*/
|
|
62
58
|
create(appName, hostContainer, options = {}) {
|
|
63
|
-
|
|
59
|
+
logger.wuDebug(`Creating sandbox for: ${appName}`);
|
|
64
60
|
|
|
65
61
|
try {
|
|
66
62
|
// π§ SHADOW DOM VERIFICATION
|
|
@@ -71,13 +67,13 @@ export class WuSandbox {
|
|
|
71
67
|
// π οΈ SMART CLEANUP: Handle existing shadow roots
|
|
72
68
|
let shadowRoot;
|
|
73
69
|
if (hostContainer.shadowRoot) {
|
|
74
|
-
|
|
70
|
+
logger.wuDebug(`Existing shadow root detected for ${appName}, performing cleanup...`);
|
|
75
71
|
|
|
76
72
|
// Clear existing shadow root content
|
|
77
73
|
hostContainer.shadowRoot.innerHTML = '';
|
|
78
74
|
shadowRoot = hostContainer.shadowRoot;
|
|
79
75
|
|
|
80
|
-
|
|
76
|
+
logger.wuDebug(`Existing shadow root cleaned and reused for ${appName}`);
|
|
81
77
|
} else {
|
|
82
78
|
// Create new Shadow DOM
|
|
83
79
|
shadowRoot = hostContainer.attachShadow({
|
|
@@ -85,7 +81,7 @@ export class WuSandbox {
|
|
|
85
81
|
delegatesFocus: true
|
|
86
82
|
});
|
|
87
83
|
|
|
88
|
-
|
|
84
|
+
logger.wuDebug(`New shadow root created for ${appName}`);
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
// π― Create app container with advanced features
|
|
@@ -103,12 +99,12 @@ export class WuSandbox {
|
|
|
103
99
|
shadowRoot.appendChild(baseStyles);
|
|
104
100
|
shadowRoot.appendChild(appContainer);
|
|
105
101
|
|
|
106
|
-
//
|
|
107
|
-
const jsScope = this.createJSScope(appName);
|
|
108
|
-
|
|
109
|
-
// π‘οΈ NUEVO: Crear JS Sandbox avanzado (ProxySandbox o SnapshotSandbox)
|
|
102
|
+
// Create JS Sandbox with container reference for DOM/storage scoping
|
|
110
103
|
const jsSandbox = this.createAdvancedJSSandbox(appName);
|
|
111
|
-
|
|
104
|
+
if (jsSandbox.setContainer) {
|
|
105
|
+
jsSandbox.setContainer(appContainer, shadowRoot);
|
|
106
|
+
}
|
|
107
|
+
const jsProxy = jsSandbox.activate();
|
|
112
108
|
|
|
113
109
|
// Verificar styleMode del manifest antes de inyectar estilos
|
|
114
110
|
const styleMode = options.styleMode || options.manifest?.styleMode;
|
|
@@ -118,7 +114,6 @@ export class WuSandbox {
|
|
|
118
114
|
shadowRoot,
|
|
119
115
|
container: appContainer,
|
|
120
116
|
hostContainer,
|
|
121
|
-
jsScope, // LEGACY: mantener para compatibilidad
|
|
122
117
|
jsSandbox, // NUEVO: ProxySandbox o SnapshotSandbox
|
|
123
118
|
jsProxy, // NUEVO: Proxy para ejecutar scripts
|
|
124
119
|
styles: baseStyles,
|
|
@@ -137,42 +132,42 @@ export class WuSandbox {
|
|
|
137
132
|
if (styleMode === 'isolated') {
|
|
138
133
|
// π MODO ISOLATED: Encapsulamiento nativo del Shadow DOM
|
|
139
134
|
// No se inyectan estilos externos - la app debe manejar sus propios estilos
|
|
140
|
-
|
|
135
|
+
logger.wuDebug(`Style mode "isolated" for ${appName}, using native Shadow DOM encapsulation`);
|
|
141
136
|
sandbox.stylesReady = Promise.resolve(0);
|
|
142
137
|
// No configurar observer de estilos - la app es responsable de sus propios estilos
|
|
143
138
|
|
|
144
139
|
} else if (styleMode === 'fully-isolated') {
|
|
145
|
-
|
|
140
|
+
logger.wuDebug(`Style mode "fully-isolated" detected for ${appName}, using enhanced style injection`);
|
|
146
141
|
// Registrar esta app como fully-isolated en el style bridge para filtrar sus estilos
|
|
147
142
|
const appUrl = options.appUrl || (options.manifest?.name ? `/${options.manifest.name}/` : `/${appName}/`);
|
|
148
143
|
this.styleBridge.registerFullyIsolatedApp(appName, appUrl);
|
|
149
|
-
|
|
144
|
+
|
|
150
145
|
// Guardar appUrl en sandbox para uso en reinjectStyles
|
|
151
146
|
sandbox.appUrl = appUrl;
|
|
152
|
-
|
|
147
|
+
|
|
153
148
|
// Para fully-isolated, inyectar SOLO los estilos propios de la app en su Shadow DOM
|
|
154
149
|
// Guardamos referencia a this para usar en el observer
|
|
155
150
|
const self = this;
|
|
156
|
-
|
|
151
|
+
|
|
157
152
|
sandbox.stylesReady = new Promise((resolve) => {
|
|
158
153
|
let resolved = false;
|
|
159
|
-
|
|
154
|
+
|
|
160
155
|
const tryInject = async () => {
|
|
161
156
|
const count = await self.injectOwnStylesToShadow(shadowRoot, appName, appUrl);
|
|
162
|
-
|
|
157
|
+
|
|
163
158
|
if (count > 0) {
|
|
164
|
-
|
|
159
|
+
logger.wuDebug(`Injected ${count} own styles for ${appName} (fully-isolated)`);
|
|
165
160
|
if (!resolved) {
|
|
166
161
|
resolved = true;
|
|
167
162
|
resolve(count);
|
|
168
163
|
}
|
|
169
164
|
}
|
|
170
|
-
|
|
165
|
+
|
|
171
166
|
return count;
|
|
172
167
|
};
|
|
173
|
-
|
|
168
|
+
|
|
174
169
|
// Usar MutationObserver PERSISTENTE para detectar cuando se inyectan estilos del app
|
|
175
|
-
|
|
170
|
+
logger.wuDebug(`Setting up style observer for ${appName} (fully-isolated)`);
|
|
176
171
|
const observer = new MutationObserver((mutations) => {
|
|
177
172
|
let newStyleCount = 0;
|
|
178
173
|
for (const m of mutations) {
|
|
@@ -182,27 +177,27 @@ export class WuSandbox {
|
|
|
182
177
|
newStyleCount++;
|
|
183
178
|
const viteId = n.getAttribute ? n.getAttribute('data-vite-dev-id') : null;
|
|
184
179
|
if (viteId && viteId.toLowerCase().includes(appName.toLowerCase())) {
|
|
185
|
-
|
|
180
|
+
logger.wuDebug(`New ${appName} style detected: ${viteId.split('/').pop()}`);
|
|
186
181
|
}
|
|
187
182
|
}
|
|
188
183
|
}
|
|
189
184
|
}
|
|
190
185
|
}
|
|
191
186
|
if (newStyleCount > 0) {
|
|
192
|
-
|
|
187
|
+
logger.wuDebug(`${newStyleCount} new styles detected in head, checking for ${appName}...`);
|
|
193
188
|
tryInject();
|
|
194
189
|
}
|
|
195
190
|
});
|
|
196
|
-
|
|
191
|
+
|
|
197
192
|
// Observar cambios en el head DE FORMA PERSISTENTE
|
|
198
193
|
observer.observe(document.head, {
|
|
199
194
|
childList: true,
|
|
200
195
|
subtree: true
|
|
201
196
|
});
|
|
202
|
-
|
|
197
|
+
|
|
203
198
|
// Guardar referencia al observer para poder desconectarlo cuando se desmonte la app
|
|
204
199
|
sandbox.styleObserver = observer;
|
|
205
|
-
|
|
200
|
+
|
|
206
201
|
// Intento inicial con pequeΓ±o delay para que Vite procese los imports
|
|
207
202
|
setTimeout(async () => {
|
|
208
203
|
const count = await tryInject();
|
|
@@ -210,9 +205,9 @@ export class WuSandbox {
|
|
|
210
205
|
if (!resolved) {
|
|
211
206
|
setTimeout(() => {
|
|
212
207
|
if (!resolved) {
|
|
213
|
-
|
|
208
|
+
logger.wuWarn(`No own styles found for ${appName} after timeout, using FALLBACK`);
|
|
214
209
|
const fallbackCount = self.injectAllStylesToShadow(shadowRoot, appName);
|
|
215
|
-
|
|
210
|
+
logger.wuDebug(`FALLBACK: Injected ${fallbackCount} styles for ${appName}`);
|
|
216
211
|
resolved = true;
|
|
217
212
|
resolve(fallbackCount);
|
|
218
213
|
}
|
|
@@ -222,21 +217,21 @@ export class WuSandbox {
|
|
|
222
217
|
});
|
|
223
218
|
} else {
|
|
224
219
|
// π MODO SHARED (default): Inyectar todos los estilos compartidos del documento
|
|
225
|
-
|
|
220
|
+
logger.wuDebug(`Style mode "shared" for ${appName}, injecting all shared styles...`);
|
|
226
221
|
sandbox.stylesReady = this.styleBridge.injectStylesIntoShadow(shadowRoot, appName, styleMode).then(count => {
|
|
227
|
-
|
|
222
|
+
logger.wuDebug(`Shared ${count} styles with ${appName}`);
|
|
228
223
|
|
|
229
224
|
// π Observar cambios dinΓ‘micos de estilos (HMR de Vite)
|
|
230
225
|
this.styleBridge.observeStyleChanges(() => {
|
|
231
|
-
|
|
226
|
+
logger.wuDebug(`Reinjecting styles for ${appName} due to changes`);
|
|
232
227
|
this.styleBridge.injectStylesIntoShadow(shadowRoot, appName, styleMode).catch(err => {
|
|
233
|
-
|
|
228
|
+
logger.wuWarn(`Failed to reinject styles: ${err}`);
|
|
234
229
|
});
|
|
235
230
|
});
|
|
236
231
|
|
|
237
232
|
return count;
|
|
238
233
|
}).catch(error => {
|
|
239
|
-
|
|
234
|
+
logger.wuWarn(`Failed to inject styles: ${error}`);
|
|
240
235
|
return 0;
|
|
241
236
|
});
|
|
242
237
|
}
|
|
@@ -244,11 +239,11 @@ export class WuSandbox {
|
|
|
244
239
|
// π Register in sandbox registry
|
|
245
240
|
this.sandboxes.set(appName, sandbox);
|
|
246
241
|
|
|
247
|
-
|
|
242
|
+
logger.wuDebug(`Enhanced sandbox created for ${appName}`);
|
|
248
243
|
return sandbox;
|
|
249
244
|
|
|
250
245
|
} catch (error) {
|
|
251
|
-
|
|
246
|
+
logger.wuError(`Failed to create sandbox for ${appName}: ${error}`);
|
|
252
247
|
|
|
253
248
|
// π§ FALLBACK RECOVERY: Create fallback sandbox when Shadow DOM fails
|
|
254
249
|
if (error.message.includes('Shadow root cannot be created')) {
|
|
@@ -263,7 +258,7 @@ export class WuSandbox {
|
|
|
263
258
|
* π§ FALLBACK SANDBOX: Create fallback container when Shadow DOM is not available
|
|
264
259
|
*/
|
|
265
260
|
createFallbackSandbox(appName, hostContainer) {
|
|
266
|
-
|
|
261
|
+
logger.wuDebug(`Creating fallback sandbox for ${appName}...`);
|
|
267
262
|
|
|
268
263
|
try {
|
|
269
264
|
// π οΈ Complete shadow DOM reset
|
|
@@ -291,7 +286,6 @@ export class WuSandbox {
|
|
|
291
286
|
shadowRoot: null, // No shadow DOM in fallback mode
|
|
292
287
|
container: fallbackContainer,
|
|
293
288
|
hostContainer,
|
|
294
|
-
jsScope: this.createJSScope(appName),
|
|
295
289
|
styles: null,
|
|
296
290
|
created: Date.now(),
|
|
297
291
|
sandbox_state: 'fallback_mode',
|
|
@@ -301,11 +295,11 @@ export class WuSandbox {
|
|
|
301
295
|
|
|
302
296
|
this.sandboxes.set(appName, healedSandbox);
|
|
303
297
|
|
|
304
|
-
|
|
298
|
+
logger.wuDebug(`Fallback sandbox created successfully for ${appName}`);
|
|
305
299
|
return healedSandbox;
|
|
306
300
|
|
|
307
301
|
} catch (healingError) {
|
|
308
|
-
|
|
302
|
+
logger.wuError(`Fallback sandbox creation failed: ${healingError}`);
|
|
309
303
|
throw healingError;
|
|
310
304
|
}
|
|
311
305
|
}
|
|
@@ -409,10 +403,10 @@ export class WuSandbox {
|
|
|
409
403
|
|
|
410
404
|
if (this.sandboxStrategy === 'proxy') {
|
|
411
405
|
jsSandbox = new WuProxySandbox(appName);
|
|
412
|
-
|
|
406
|
+
logger.wuDebug(`Created ProxySandbox for ${appName}`);
|
|
413
407
|
} else {
|
|
414
408
|
jsSandbox = new WuSnapshotSandbox(appName);
|
|
415
|
-
|
|
409
|
+
logger.wuDebug(`Created SnapshotSandbox for ${appName}`);
|
|
416
410
|
}
|
|
417
411
|
|
|
418
412
|
// Registrar sandbox
|
|
@@ -421,178 +415,6 @@ export class WuSandbox {
|
|
|
421
415
|
return jsSandbox;
|
|
422
416
|
}
|
|
423
417
|
|
|
424
|
-
/**
|
|
425
|
-
* π Ejecutar script en sandbox aislado
|
|
426
|
-
* @param {string} script - CΓ³digo JavaScript
|
|
427
|
-
* @param {string} appName - Nombre de la app
|
|
428
|
-
* @param {string} strategy - 'function' | 'eval' | 'auto'
|
|
429
|
-
* @returns {*} Resultado de la ejecuciΓ³n
|
|
430
|
-
*/
|
|
431
|
-
executeScript(script, appName, strategy = 'function') {
|
|
432
|
-
const sandbox = this.sandboxes.get(appName);
|
|
433
|
-
if (!sandbox || !sandbox.jsProxy) {
|
|
434
|
-
throw new Error(`Sandbox not found for ${appName}`);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
console.log(`[WuSandbox] π Executing script for ${appName}`);
|
|
438
|
-
return this.scriptExecutor.execute(script, appName, sandbox.jsProxy, strategy);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* π Parsear HTML de micro-app
|
|
443
|
-
* @param {string} html - HTML a parsear
|
|
444
|
-
* @param {string} appName - Nombre de la app
|
|
445
|
-
* @param {string} baseUrl - URL base
|
|
446
|
-
* @returns {Object} Resultado del parsing
|
|
447
|
-
*/
|
|
448
|
-
parseHtml(html, appName, baseUrl) {
|
|
449
|
-
console.log(`[WuSandbox] π Parsing HTML for ${appName}`);
|
|
450
|
-
return this.htmlParser.parse(html, appName, baseUrl);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
* π Parsear HTML desde URL
|
|
455
|
-
* @param {string} url - URL de la app
|
|
456
|
-
* @param {string} appName - Nombre de la app
|
|
457
|
-
* @returns {Promise<Object>} Resultado del parsing
|
|
458
|
-
*/
|
|
459
|
-
async parseHtmlFromUrl(url, appName) {
|
|
460
|
-
console.log(`[WuSandbox] π Parsing HTML from URL for ${appName}`);
|
|
461
|
-
return await this.htmlParser.parseFromUrl(url, appName);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Obtener estilos base para el sandbox
|
|
466
|
-
* @param {string} appName - Nombre de la aplicaciΓ³n
|
|
467
|
-
* @returns {string} CSS base
|
|
468
|
-
*/
|
|
469
|
-
getBaseStyles(appName) {
|
|
470
|
-
return `
|
|
471
|
-
/* Wu Framework - Shadow DOM Base Styles */
|
|
472
|
-
:host {
|
|
473
|
-
display: block;
|
|
474
|
-
width: 100%;
|
|
475
|
-
height: 100%;
|
|
476
|
-
box-sizing: border-box;
|
|
477
|
-
contain: layout style paint;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
.wu-app-root {
|
|
481
|
-
width: 100%;
|
|
482
|
-
height: 100%;
|
|
483
|
-
box-sizing: border-box;
|
|
484
|
-
isolation: isolate;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/* Reset bΓ‘sico para evitar conflictos */
|
|
488
|
-
* {
|
|
489
|
-
box-sizing: border-box;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/* Variables CSS aisladas para la app */
|
|
493
|
-
:host {
|
|
494
|
-
--wu-app-name: "${appName}";
|
|
495
|
-
--wu-isolation: true;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/* Prevenir scroll del host cuando no es necesario */
|
|
499
|
-
:host([wu-no-scroll]) {
|
|
500
|
-
overflow: hidden;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
/* Estilos para debugging en desarrollo */
|
|
504
|
-
:host([wu-debug]) {
|
|
505
|
-
border: 2px dashed #ff6b6b;
|
|
506
|
-
background: rgba(255, 107, 107, 0.1);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
:host([wu-debug])::before {
|
|
510
|
-
content: "Wu App: " attr(wu-app);
|
|
511
|
-
position: absolute;
|
|
512
|
-
top: 0;
|
|
513
|
-
left: 0;
|
|
514
|
-
background: #ff6b6b;
|
|
515
|
-
color: white;
|
|
516
|
-
padding: 2px 6px;
|
|
517
|
-
font-size: 10px;
|
|
518
|
-
font-family: monospace;
|
|
519
|
-
z-index: 10000;
|
|
520
|
-
}
|
|
521
|
-
`;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Crear scope aislado para JavaScript
|
|
526
|
-
* @param {string} appName - Nombre de la aplicaciΓ³n
|
|
527
|
-
* @returns {Proxy} Proxy que aΓsla el scope global
|
|
528
|
-
*/
|
|
529
|
-
createJSScope(appName) {
|
|
530
|
-
// Crear namespace aislado para la app
|
|
531
|
-
const appGlobals = Object.create(null);
|
|
532
|
-
|
|
533
|
-
// Proxy que intercepta acceso a variables globales
|
|
534
|
-
return new Proxy(window, {
|
|
535
|
-
set(target, prop, value) {
|
|
536
|
-
// Variables especΓficas de la app van al namespace aislado
|
|
537
|
-
if (this.isAppSpecific(prop)) {
|
|
538
|
-
appGlobals[prop] = value;
|
|
539
|
-
console.log(`[WuSandbox] π App ${appName} set isolated global: ${String(prop)}`);
|
|
540
|
-
return true;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// Variables seguras pueden ir al global real
|
|
544
|
-
if (this.isSafeGlobal(prop)) {
|
|
545
|
-
target[prop] = value;
|
|
546
|
-
return true;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// Por defecto, aislar en el namespace de la app
|
|
550
|
-
appGlobals[prop] = value;
|
|
551
|
-
return true;
|
|
552
|
-
},
|
|
553
|
-
|
|
554
|
-
get(target, prop) {
|
|
555
|
-
// Primero buscar en namespace aislado
|
|
556
|
-
if (prop in appGlobals) {
|
|
557
|
-
return appGlobals[prop];
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// Luego en el global real
|
|
561
|
-
return target[prop];
|
|
562
|
-
},
|
|
563
|
-
|
|
564
|
-
has(target, prop) {
|
|
565
|
-
return prop in appGlobals || prop in target;
|
|
566
|
-
},
|
|
567
|
-
|
|
568
|
-
ownKeys(target) {
|
|
569
|
-
return [...Object.keys(appGlobals), ...Object.keys(target)];
|
|
570
|
-
},
|
|
571
|
-
|
|
572
|
-
// MΓ©todos auxiliares
|
|
573
|
-
isAppSpecific(prop) {
|
|
574
|
-
const appSpecificPatterns = [
|
|
575
|
-
/^app[A-Z]/, // appData, appConfig, etc.
|
|
576
|
-
/^[a-z]+App$/, // myApp, headerApp, etc.
|
|
577
|
-
/^__[a-zA-Z]/, // variables privadas
|
|
578
|
-
/^_[A-Z]/ // variables de librerΓas
|
|
579
|
-
];
|
|
580
|
-
|
|
581
|
-
return appSpecificPatterns.some(pattern => pattern.test(String(prop)));
|
|
582
|
-
},
|
|
583
|
-
|
|
584
|
-
isSafeGlobal(prop) {
|
|
585
|
-
const safeGlobals = new Set([
|
|
586
|
-
'console', 'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval',
|
|
587
|
-
'fetch', 'URL', 'URLSearchParams', 'FormData', 'Blob',
|
|
588
|
-
'Date', 'Math', 'JSON', 'Promise', 'Array', 'Object', 'String', 'Number'
|
|
589
|
-
]);
|
|
590
|
-
|
|
591
|
-
return safeGlobals.has(String(prop));
|
|
592
|
-
}
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
|
|
596
418
|
/**
|
|
597
419
|
* Agregar estilos personalizados al sandbox
|
|
598
420
|
* @param {string} appName - Nombre de la aplicaciΓ³n
|
|
@@ -601,7 +423,7 @@ export class WuSandbox {
|
|
|
601
423
|
addStyles(appName, css) {
|
|
602
424
|
const sandbox = this.sandboxes.get(appName);
|
|
603
425
|
if (!sandbox) {
|
|
604
|
-
|
|
426
|
+
logger.wuWarn(`Sandbox not found for: ${appName}`);
|
|
605
427
|
return;
|
|
606
428
|
}
|
|
607
429
|
|
|
@@ -610,7 +432,7 @@ export class WuSandbox {
|
|
|
610
432
|
styleElement.setAttribute('wu-custom-styles', '');
|
|
611
433
|
|
|
612
434
|
sandbox.shadowRoot.appendChild(styleElement);
|
|
613
|
-
|
|
435
|
+
logger.wuDebug(`Custom styles added to ${appName}`);
|
|
614
436
|
}
|
|
615
437
|
|
|
616
438
|
/**
|
|
@@ -621,7 +443,7 @@ export class WuSandbox {
|
|
|
621
443
|
loadExternalStyles(appName, href) {
|
|
622
444
|
const sandbox = this.sandboxes.get(appName);
|
|
623
445
|
if (!sandbox) {
|
|
624
|
-
|
|
446
|
+
logger.wuWarn(`Sandbox not found for: ${appName}`);
|
|
625
447
|
return;
|
|
626
448
|
}
|
|
627
449
|
|
|
@@ -631,7 +453,7 @@ export class WuSandbox {
|
|
|
631
453
|
linkElement.setAttribute('wu-external-styles', '');
|
|
632
454
|
|
|
633
455
|
sandbox.shadowRoot.appendChild(linkElement);
|
|
634
|
-
|
|
456
|
+
logger.wuDebug(`External styles loaded in ${appName}: ${href}`);
|
|
635
457
|
}
|
|
636
458
|
|
|
637
459
|
/**
|
|
@@ -642,7 +464,7 @@ export class WuSandbox {
|
|
|
642
464
|
setDebugMode(appName, enabled = true) {
|
|
643
465
|
const sandbox = this.sandboxes.get(appName);
|
|
644
466
|
if (!sandbox) {
|
|
645
|
-
|
|
467
|
+
logger.wuWarn(`Sandbox not found for: ${appName}`);
|
|
646
468
|
return;
|
|
647
469
|
}
|
|
648
470
|
|
|
@@ -654,7 +476,7 @@ export class WuSandbox {
|
|
|
654
476
|
sandbox.hostContainer.removeAttribute('wu-app');
|
|
655
477
|
}
|
|
656
478
|
|
|
657
|
-
|
|
479
|
+
logger.wuDebug(`Debug mode ${enabled ? 'enabled' : 'disabled'} for ${appName}`);
|
|
658
480
|
}
|
|
659
481
|
|
|
660
482
|
/**
|
|
@@ -666,13 +488,13 @@ export class WuSandbox {
|
|
|
666
488
|
|
|
667
489
|
const { appName, shadowRoot, hostContainer, jsSandbox } = sandbox;
|
|
668
490
|
|
|
669
|
-
|
|
491
|
+
logger.wuDebug(`Cleaning up sandbox for: ${appName}`);
|
|
670
492
|
|
|
671
493
|
try {
|
|
672
494
|
// π‘οΈ NUEVO: Desactivar JS Sandbox
|
|
673
495
|
if (jsSandbox && jsSandbox.isActive()) {
|
|
674
496
|
jsSandbox.deactivate();
|
|
675
|
-
|
|
497
|
+
logger.wuDebug(`JS Sandbox deactivated for ${appName}`);
|
|
676
498
|
}
|
|
677
499
|
|
|
678
500
|
// Limpiar eventos y observers
|
|
@@ -694,10 +516,10 @@ export class WuSandbox {
|
|
|
694
516
|
this.sandboxes.delete(appName);
|
|
695
517
|
this.jsSandboxes.delete(appName);
|
|
696
518
|
|
|
697
|
-
|
|
519
|
+
logger.wuDebug(`Sandbox cleaned up: ${appName}`);
|
|
698
520
|
|
|
699
521
|
} catch (error) {
|
|
700
|
-
|
|
522
|
+
logger.wuError(`Error cleaning up sandbox ${appName}: ${error}`);
|
|
701
523
|
}
|
|
702
524
|
}
|
|
703
525
|
|
|
@@ -748,8 +570,6 @@ export class WuSandbox {
|
|
|
748
570
|
total: this.sandboxes.size,
|
|
749
571
|
sandboxes: Array.from(this.sandboxes.keys()),
|
|
750
572
|
jsSandboxes: Array.from(this.jsSandboxes.keys()),
|
|
751
|
-
htmlCacheSize: this.htmlParser.getStats().cacheSize,
|
|
752
|
-
scriptExecutor: this.scriptExecutor.getStats(),
|
|
753
573
|
details: Array.from(this.sandboxes.entries()).map(([name, sandbox]) => ({
|
|
754
574
|
name,
|
|
755
575
|
uptime: Date.now() - sandbox.created,
|
|
@@ -764,20 +584,18 @@ export class WuSandbox {
|
|
|
764
584
|
* Limpiar todos los sandboxes
|
|
765
585
|
*/
|
|
766
586
|
cleanupAll() {
|
|
767
|
-
|
|
587
|
+
logger.wuDebug(`Cleaning up all ${this.sandboxes.size} sandboxes...`);
|
|
768
588
|
|
|
769
589
|
for (const [appName, sandbox] of this.sandboxes) {
|
|
770
590
|
this.cleanup(sandbox);
|
|
771
591
|
}
|
|
772
592
|
|
|
773
|
-
this.globalState.clear();
|
|
774
|
-
|
|
775
593
|
// Limpiar StyleBridge
|
|
776
594
|
if (this.styleBridge) {
|
|
777
595
|
this.styleBridge.cleanup();
|
|
778
596
|
}
|
|
779
597
|
|
|
780
|
-
|
|
598
|
+
logger.wuDebug('All sandboxes cleaned up');
|
|
781
599
|
}
|
|
782
600
|
|
|
783
601
|
/**
|
|
@@ -787,7 +605,7 @@ export class WuSandbox {
|
|
|
787
605
|
configureStyleSharing(config) {
|
|
788
606
|
if (this.styleBridge) {
|
|
789
607
|
this.styleBridge.configure(config);
|
|
790
|
-
|
|
608
|
+
logger.wuDebug('StyleBridge configured');
|
|
791
609
|
}
|
|
792
610
|
}
|
|
793
611
|
|
|
@@ -806,7 +624,7 @@ export class WuSandbox {
|
|
|
806
624
|
async reinjectStyles(appName) {
|
|
807
625
|
const sandbox = this.sandboxes.get(appName);
|
|
808
626
|
if (!sandbox || !sandbox.shadowRoot) {
|
|
809
|
-
|
|
627
|
+
logger.wuWarn(`Cannot reinject styles for ${appName}`);
|
|
810
628
|
return;
|
|
811
629
|
}
|
|
812
630
|
|
|
@@ -814,27 +632,27 @@ export class WuSandbox {
|
|
|
814
632
|
|
|
815
633
|
// π MODO ISOLATED: No reinyectar estilos - la app maneja sus propios estilos
|
|
816
634
|
if (styleMode === 'isolated') {
|
|
817
|
-
|
|
635
|
+
logger.wuDebug(`Skipping reinject for ${appName} (isolated mode - app manages own styles)`);
|
|
818
636
|
return;
|
|
819
637
|
}
|
|
820
638
|
|
|
821
639
|
// π‘οΈ MODO FULLY-ISOLATED: Reinyectar SOLO estilos propios
|
|
822
640
|
if (styleMode === 'fully-isolated') {
|
|
823
|
-
|
|
641
|
+
logger.wuDebug(`Reinjecting OWN styles for ${appName} (fully-isolated)...`);
|
|
824
642
|
const appUrl = sandbox.appUrl || sandbox.manifest?.name ? `/${sandbox.manifest.name}/` : `/${appName}/`;
|
|
825
643
|
const count = await this.injectOwnStylesToShadow(sandbox.shadowRoot, appName, appUrl);
|
|
826
|
-
|
|
644
|
+
logger.wuDebug(`Reinjected ${count} own styles for ${appName}`);
|
|
827
645
|
return;
|
|
828
646
|
}
|
|
829
647
|
|
|
830
648
|
// π MODO SHARED: Reinyectar todos los estilos compartidos
|
|
831
|
-
|
|
649
|
+
logger.wuDebug(`Reinjecting shared styles for ${appName}...`);
|
|
832
650
|
const count = await this.styleBridge.injectStylesIntoShadow(
|
|
833
651
|
sandbox.shadowRoot,
|
|
834
652
|
appName,
|
|
835
653
|
styleMode
|
|
836
654
|
);
|
|
837
|
-
|
|
655
|
+
logger.wuDebug(`Reinjected ${count} shared styles`);
|
|
838
656
|
}
|
|
839
657
|
|
|
840
658
|
/**
|
|
@@ -849,11 +667,11 @@ export class WuSandbox {
|
|
|
849
667
|
if (!shadowRoot) return 0;
|
|
850
668
|
|
|
851
669
|
let injectedCount = 0;
|
|
852
|
-
|
|
670
|
+
|
|
853
671
|
// Buscar TODOS los estilos en el head
|
|
854
672
|
const allStyles = document.querySelectorAll('style');
|
|
855
673
|
const normalizedAppName = appName.toLowerCase();
|
|
856
|
-
|
|
674
|
+
|
|
857
675
|
// Patrones para detectar estilos de esta app (Windows y Unix paths)
|
|
858
676
|
// IMPORTANTE: Debe coincidir SOLO con packages/appName/ al inicio del path del paquete
|
|
859
677
|
// NO debe coincidir con packages/shell/src/components/learning/ (eso es del shell)
|
|
@@ -862,9 +680,9 @@ export class WuSandbox {
|
|
|
862
680
|
// El src/ es clave para asegurar que es el MFE, no un subdirectorio de otro package
|
|
863
681
|
new RegExp(`packages[/\\\\]${normalizedAppName}[/\\\\]src[/\\\\]`, 'i')
|
|
864
682
|
];
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
683
|
+
|
|
684
|
+
logger.wuDebug(`Searching own styles for ${appName}, found ${allStyles.length} style tags in head`);
|
|
685
|
+
|
|
868
686
|
// Log para debug: mostrar estilos que contienen el nombre de la app
|
|
869
687
|
let matchingCount = 0;
|
|
870
688
|
for (const s of allStyles) {
|
|
@@ -874,18 +692,18 @@ export class WuSandbox {
|
|
|
874
692
|
}
|
|
875
693
|
}
|
|
876
694
|
if (matchingCount > 0) {
|
|
877
|
-
|
|
695
|
+
logger.wuDebug(`Found ${matchingCount} styles potentially matching ${appName}`);
|
|
878
696
|
}
|
|
879
|
-
|
|
697
|
+
|
|
880
698
|
for (const style of allStyles) {
|
|
881
699
|
// NO saltar basΓ‘ndose en data-wu-injected del head - eso se pone en los clones del shadow DOM
|
|
882
|
-
|
|
700
|
+
|
|
883
701
|
const viteId = style.getAttribute('data-vite-dev-id') || '';
|
|
884
702
|
const normalizedViteId = viteId.replace(/\\/g, '/').toLowerCase();
|
|
885
|
-
|
|
703
|
+
|
|
886
704
|
// Verificar si el estilo pertenece a esta app
|
|
887
705
|
let belongsToApp = false;
|
|
888
|
-
|
|
706
|
+
|
|
889
707
|
// 1. Por data-vite-dev-id (la forma mΓ‘s confiable)
|
|
890
708
|
if (viteId) {
|
|
891
709
|
// Revisar si el path contiene packages/appName/
|
|
@@ -903,23 +721,23 @@ export class WuSandbox {
|
|
|
903
721
|
}
|
|
904
722
|
}
|
|
905
723
|
}
|
|
906
|
-
|
|
724
|
+
|
|
907
725
|
if (belongsToApp) {
|
|
908
726
|
// Verificar si ya existe en el Shadow DOM
|
|
909
727
|
const existingStyle = shadowRoot.querySelector(`style[data-vite-dev-id="${viteId}"]`);
|
|
910
|
-
|
|
728
|
+
|
|
911
729
|
if (!existingStyle) {
|
|
912
730
|
const clonedStyle = style.cloneNode(true);
|
|
913
731
|
clonedStyle.setAttribute('data-wu-injected', 'true');
|
|
914
732
|
shadowRoot.insertBefore(clonedStyle, shadowRoot.firstChild);
|
|
915
733
|
injectedCount++;
|
|
916
734
|
const styleName = viteId.substring(viteId.lastIndexOf('/') + 1) || viteId.substring(viteId.lastIndexOf('\\') + 1);
|
|
917
|
-
|
|
735
|
+
logger.wuDebug(`Injected own style for ${appName}: ${styleName}`);
|
|
918
736
|
}
|
|
919
737
|
}
|
|
920
738
|
}
|
|
921
|
-
|
|
922
|
-
|
|
739
|
+
|
|
740
|
+
logger.wuDebug(`Total own styles injected for ${appName}: ${injectedCount}`);
|
|
923
741
|
return injectedCount;
|
|
924
742
|
}
|
|
925
743
|
|
|
@@ -935,27 +753,27 @@ export class WuSandbox {
|
|
|
935
753
|
|
|
936
754
|
let injectedCount = 0;
|
|
937
755
|
const normalizedAppName = appName.toLowerCase();
|
|
938
|
-
|
|
756
|
+
|
|
939
757
|
// Inyectar estilos que contengan el nombre de la app en su vite-id
|
|
940
758
|
const allStyles = document.querySelectorAll('style');
|
|
941
759
|
for (const style of allStyles) {
|
|
942
760
|
const viteId = style.getAttribute('data-vite-dev-id') || '';
|
|
943
|
-
|
|
761
|
+
|
|
944
762
|
// Solo inyectar si contiene el nombre de la app
|
|
945
763
|
if (!viteId.toLowerCase().includes(normalizedAppName)) continue;
|
|
946
|
-
|
|
764
|
+
|
|
947
765
|
// Verificar si ya existe en el shadow DOM
|
|
948
766
|
if (shadowRoot.querySelector(`style[data-vite-dev-id="${viteId}"]`)) continue;
|
|
949
|
-
|
|
767
|
+
|
|
950
768
|
const clonedStyle = style.cloneNode(true);
|
|
951
769
|
clonedStyle.setAttribute('data-wu-fallback', 'true');
|
|
952
770
|
shadowRoot.insertBefore(clonedStyle, shadowRoot.firstChild);
|
|
953
771
|
injectedCount++;
|
|
954
772
|
const styleName = viteId.split('/').pop() || viteId.split('\\').pop();
|
|
955
|
-
|
|
773
|
+
logger.wuDebug(`FALLBACK injected: ${styleName}`);
|
|
956
774
|
}
|
|
957
|
-
|
|
958
|
-
|
|
775
|
+
|
|
776
|
+
logger.wuDebug(`FALLBACK: Total ${injectedCount} styles injected for ${appName}`);
|
|
959
777
|
return injectedCount;
|
|
960
778
|
}
|
|
961
|
-
}
|
|
779
|
+
}
|