wu-framework 1.0.4 → 1.0.5
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/package.json +1 -1
- package/src/core/wu-logger.js +18 -2
- package/src/core/wu-registry.js +9 -92
- package/src/index.js +15 -1
- package/src/api/wu-simple.js +0 -316
package/package.json
CHANGED
package/src/core/wu-logger.js
CHANGED
|
@@ -7,7 +7,8 @@ export class WuLogger {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
// Detectar entorno automáticamente
|
|
9
9
|
this.isDevelopment = this.detectEnvironment();
|
|
10
|
-
|
|
10
|
+
// En desarrollo: warn (menos ruido), en producción: error
|
|
11
|
+
this.logLevel = this.isDevelopment ? 'warn' : 'error';
|
|
11
12
|
|
|
12
13
|
this.levels = {
|
|
13
14
|
debug: 0,
|
|
@@ -116,4 +117,19 @@ export const wuLog = {
|
|
|
116
117
|
info: (...args) => logger.wuInfo(...args),
|
|
117
118
|
warn: (...args) => logger.wuWarn(...args),
|
|
118
119
|
error: (...args) => logger.wuError(...args)
|
|
119
|
-
};
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 🔇 Silenciar todos los logs de Wu Framework
|
|
124
|
+
* Útil en producción para eliminar todo el ruido
|
|
125
|
+
*/
|
|
126
|
+
export function silenceAllLogs() {
|
|
127
|
+
logger.setLevel('silent');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 🔊 Restaurar logs (nivel debug)
|
|
132
|
+
*/
|
|
133
|
+
export function enableAllLogs() {
|
|
134
|
+
logger.setLevel('debug');
|
|
135
|
+
}
|
package/src/core/wu-registry.js
CHANGED
|
@@ -1,52 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 🔔 WU-REGISTRY:
|
|
3
|
-
*
|
|
4
|
-
* Reemplaza el polling con Custom Events para mejor performance
|
|
2
|
+
* 🔔 WU-REGISTRY: APP REGISTRATION TRACKER
|
|
3
|
+
* Simplificado - solo trackea apps registradas
|
|
5
4
|
*/
|
|
6
5
|
|
|
7
6
|
export class WuRegistry {
|
|
8
7
|
constructor() {
|
|
9
8
|
this.registeredApps = new Set();
|
|
10
|
-
this.waitingPromises = new Map();
|
|
11
|
-
|
|
12
|
-
// Event listeners para registro
|
|
13
|
-
this.setupEventListeners();
|
|
14
|
-
|
|
15
|
-
console.log('[WuRegistry] 🔔 Event-based registration system initialized');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 📡 SETUP EVENT LISTENERS
|
|
20
|
-
*/
|
|
21
|
-
setupEventListeners() {
|
|
22
|
-
// Escuchar eventos de registro de apps
|
|
23
|
-
window.addEventListener('wu:app:ready', (event) => {
|
|
24
|
-
const { appName } = event.detail;
|
|
25
|
-
console.log(`[WuRegistry] ✅ App registered via event: ${appName}`);
|
|
26
|
-
|
|
27
|
-
this.registeredApps.add(appName);
|
|
28
|
-
|
|
29
|
-
// Resolver promesas pendientes
|
|
30
|
-
if (this.waitingPromises.has(appName)) {
|
|
31
|
-
const { resolve } = this.waitingPromises.get(appName);
|
|
32
|
-
resolve();
|
|
33
|
-
this.waitingPromises.delete(appName);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// API para que apps notifiquen que están listas (se agrega a window.wu cuando exista)
|
|
38
|
-
// No crear window.wu aquí - eso lo hace index.js con la instancia completa
|
|
39
9
|
this._setupNotifyReady();
|
|
40
10
|
}
|
|
41
11
|
|
|
42
12
|
/**
|
|
43
|
-
* 🔔 Setup notifyReady API
|
|
13
|
+
* 🔔 Setup notifyReady API en window.wu
|
|
44
14
|
*/
|
|
45
15
|
_setupNotifyReady() {
|
|
46
16
|
const setupFn = () => {
|
|
47
17
|
if (window.wu && !window.wu.notifyReady) {
|
|
48
18
|
window.wu.notifyReady = (appName) => {
|
|
49
|
-
console.log(`[WuRegistry] 📢 App ${appName} called notifyReady()`);
|
|
50
19
|
const event = new CustomEvent('wu:app:ready', {
|
|
51
20
|
detail: { appName, timestamp: Date.now() }
|
|
52
21
|
});
|
|
@@ -55,89 +24,37 @@ export class WuRegistry {
|
|
|
55
24
|
}
|
|
56
25
|
};
|
|
57
26
|
|
|
58
|
-
// Intentar setup inmediato
|
|
59
27
|
setupFn();
|
|
60
|
-
|
|
61
|
-
// Si window.wu no existe aún, esperar un tick
|
|
62
28
|
if (!window.wu) {
|
|
63
29
|
queueMicrotask(setupFn);
|
|
64
30
|
}
|
|
65
31
|
}
|
|
66
32
|
|
|
67
33
|
/**
|
|
68
|
-
*
|
|
69
|
-
* @param {string} appName - Nombre de la app
|
|
70
|
-
* @param {number} timeout - Timeout en ms (default: 10000)
|
|
71
|
-
* @returns {Promise}
|
|
34
|
+
* ✅ MARK AS REGISTERED
|
|
72
35
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (this.registeredApps.has(appName)) {
|
|
76
|
-
console.log(`[WuRegistry] ⚡ App ${appName} already registered`);
|
|
77
|
-
return Promise.resolve();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
console.log(`[WuRegistry] ⏳ Waiting for app ${appName} to register...`);
|
|
81
|
-
|
|
82
|
-
return new Promise((resolve, reject) => {
|
|
83
|
-
// Guardar promesa
|
|
84
|
-
this.waitingPromises.set(appName, { resolve, reject });
|
|
85
|
-
|
|
86
|
-
// Timeout
|
|
87
|
-
const timeoutId = setTimeout(() => {
|
|
88
|
-
if (this.waitingPromises.has(appName)) {
|
|
89
|
-
this.waitingPromises.delete(appName);
|
|
90
|
-
|
|
91
|
-
const error = new Error(
|
|
92
|
-
`App '${appName}' failed to register within ${timeout}ms.\n\n` +
|
|
93
|
-
`Possible causes:\n` +
|
|
94
|
-
` - Module failed to load\n` +
|
|
95
|
-
` - wu.define() was not called\n` +
|
|
96
|
-
` - Check browser console for import errors\n\n` +
|
|
97
|
-
`Make sure your app calls:\n` +
|
|
98
|
-
` wu.define('${appName}', { mount, unmount })`
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
reject(error);
|
|
102
|
-
}
|
|
103
|
-
}, timeout);
|
|
104
|
-
|
|
105
|
-
// Limpiar timeout cuando se resuelva
|
|
106
|
-
this.waitingPromises.get(appName).timeoutId = timeoutId;
|
|
107
|
-
});
|
|
36
|
+
markAsRegistered(appName) {
|
|
37
|
+
this.registeredApps.add(appName);
|
|
108
38
|
}
|
|
109
39
|
|
|
110
40
|
/**
|
|
111
|
-
*
|
|
112
|
-
* @param {string} appName
|
|
41
|
+
* ❓ IS REGISTERED
|
|
113
42
|
*/
|
|
114
|
-
|
|
115
|
-
this.registeredApps.
|
|
116
|
-
console.log(`[WuRegistry] ✅ App ${appName} marked as registered`);
|
|
43
|
+
isRegistered(appName) {
|
|
44
|
+
return this.registeredApps.has(appName);
|
|
117
45
|
}
|
|
118
46
|
|
|
119
47
|
/**
|
|
120
48
|
* ❌ UNREGISTER APP
|
|
121
|
-
* @param {string} appName
|
|
122
49
|
*/
|
|
123
50
|
unregister(appName) {
|
|
124
51
|
this.registeredApps.delete(appName);
|
|
125
|
-
console.log(`[WuRegistry] ❌ App ${appName} unregistered`);
|
|
126
52
|
}
|
|
127
53
|
|
|
128
54
|
/**
|
|
129
55
|
* 🧹 CLEANUP
|
|
130
56
|
*/
|
|
131
57
|
cleanup() {
|
|
132
|
-
// Rechazar todas las promesas pendientes
|
|
133
|
-
for (const [appName, { reject, timeoutId }] of this.waitingPromises) {
|
|
134
|
-
clearTimeout(timeoutId);
|
|
135
|
-
reject(new Error(`Registry cleanup: ${appName}`));
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
this.waitingPromises.clear();
|
|
139
58
|
this.registeredApps.clear();
|
|
140
|
-
|
|
141
|
-
console.log('[WuRegistry] 🧹 Registry cleaned up');
|
|
142
59
|
}
|
|
143
60
|
}
|
package/src/index.js
CHANGED
|
@@ -103,7 +103,7 @@ if (typeof window !== 'undefined') {
|
|
|
103
103
|
|
|
104
104
|
// Configurar propiedades si no existen
|
|
105
105
|
if (!wu.version) {
|
|
106
|
-
wu.version = '1.0.
|
|
106
|
+
wu.version = '1.0.5';
|
|
107
107
|
console.log('🚀 Wu Framework loaded - Universal Microfrontends ready');
|
|
108
108
|
wu.info = {
|
|
109
109
|
name: 'Wu Framework',
|
|
@@ -126,6 +126,19 @@ if (typeof window !== 'undefined') {
|
|
|
126
126
|
wu.once = (eventName, callback) => wu.eventBus.once(eventName, callback);
|
|
127
127
|
wu.off = (eventName, callback) => wu.eventBus.off(eventName, callback);
|
|
128
128
|
}
|
|
129
|
+
|
|
130
|
+
// 🔇 Exponer funciones de control de logs
|
|
131
|
+
// window.wu.silence() para silenciar, window.wu.verbose() para debug
|
|
132
|
+
if (!wu.silence) {
|
|
133
|
+
wu.silence = async () => {
|
|
134
|
+
const { silenceAllLogs } = await import('./core/wu-logger.js');
|
|
135
|
+
silenceAllLogs();
|
|
136
|
+
};
|
|
137
|
+
wu.verbose = async () => {
|
|
138
|
+
const { enableAllLogs } = await import('./core/wu-logger.js');
|
|
139
|
+
enableAllLogs();
|
|
140
|
+
};
|
|
141
|
+
}
|
|
129
142
|
}
|
|
130
143
|
|
|
131
144
|
// Exportar API principal
|
|
@@ -167,6 +180,7 @@ export {
|
|
|
167
180
|
} from './core/wu-hooks.js';
|
|
168
181
|
export { WuSandboxPool } from './core/wu-sandbox-pool.js';
|
|
169
182
|
export { WuRegistry } from './core/wu-registry.js';
|
|
183
|
+
export { silenceAllLogs, enableAllLogs } from './core/wu-logger.js';
|
|
170
184
|
|
|
171
185
|
/**
|
|
172
186
|
* Utilidades de conveniencia para uso común
|
package/src/api/wu-simple.js
DELETED
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🚀 WU-FRAMEWORK SIMPLIFIED API
|
|
3
|
-
* Developer-friendly interface for universal microfrontends
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { wu as wuCore } from '../index.js'
|
|
7
|
-
import { logger } from '../core/wu-logger.js'
|
|
8
|
-
|
|
9
|
-
class WuSimpleAPI {
|
|
10
|
-
constructor() {
|
|
11
|
-
this.core = wuCore
|
|
12
|
-
this.autoInitialized = false
|
|
13
|
-
this.defaultConfig = {
|
|
14
|
-
container: '#app',
|
|
15
|
-
mode: 'auto', // auto, spa, microfrontend
|
|
16
|
-
debug: false,
|
|
17
|
-
timeout: 30000,
|
|
18
|
-
retries: 3
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 🌟 SMART MOUNT: Intelligent mounting with auto-discovery
|
|
24
|
-
* wu.mount('dashboard').into('#container')
|
|
25
|
-
* wu.mount('http://localhost:3001/dashboard')
|
|
26
|
-
*/
|
|
27
|
-
mount(appNameOrUrl) {
|
|
28
|
-
const mountAPI = {
|
|
29
|
-
into: async (containerSelector = this.defaultConfig.container) => {
|
|
30
|
-
await this._ensureInitialized()
|
|
31
|
-
|
|
32
|
-
// 🔍 Detect if it's a URL or app name
|
|
33
|
-
if (this._isUrl(appNameOrUrl)) {
|
|
34
|
-
return await this._mountFromUrl(appNameOrUrl, containerSelector)
|
|
35
|
-
} else {
|
|
36
|
-
return await this._mountFromName(appNameOrUrl, containerSelector)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Support direct call: wu.mount('dashboard', '#container')
|
|
42
|
-
if (typeof arguments[1] === 'string') {
|
|
43
|
-
return mountAPI.into(arguments[1])
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return mountAPI
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 🚀 QUICK LOAD: One-liner for loading remote microfrontends
|
|
51
|
-
* wu.load('http://localhost:3001/dashboard')
|
|
52
|
-
* wu.load('http://localhost:3001', { name: 'dashboard' })
|
|
53
|
-
*/
|
|
54
|
-
async load(url, options = {}) {
|
|
55
|
-
await this._ensureInitialized()
|
|
56
|
-
|
|
57
|
-
const appName = options.name || this._extractAppName(url)
|
|
58
|
-
const container = options.container || this.defaultConfig.container
|
|
59
|
-
|
|
60
|
-
// Auto-register and mount
|
|
61
|
-
await this._registerFromUrl(url, appName)
|
|
62
|
-
return await this.mount(appName).into(container)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 🎯 BATCH OPERATIONS: Load multiple apps at once
|
|
67
|
-
* wu.loadMany([
|
|
68
|
-
* { name: 'dashboard', url: 'http://localhost:3001' },
|
|
69
|
-
* { name: 'sidebar', url: 'http://localhost:3002' }
|
|
70
|
-
* ])
|
|
71
|
-
*/
|
|
72
|
-
async loadMany(apps) {
|
|
73
|
-
await this._ensureInitialized()
|
|
74
|
-
|
|
75
|
-
const results = []
|
|
76
|
-
for (const app of apps) {
|
|
77
|
-
try {
|
|
78
|
-
await this._registerFromUrl(app.url, app.name)
|
|
79
|
-
results.push({ name: app.name, status: 'registered' })
|
|
80
|
-
} catch (error) {
|
|
81
|
-
results.push({ name: app.name, status: 'failed', error: error.message })
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return results
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* 🔧 CONFIGURATION: Flexible configuration methods
|
|
90
|
-
* wu.config({ debug: true, timeout: 60000 })
|
|
91
|
-
* wu.debug(true)
|
|
92
|
-
* wu.timeout(30000)
|
|
93
|
-
*/
|
|
94
|
-
config(options = {}) {
|
|
95
|
-
Object.assign(this.defaultConfig, options)
|
|
96
|
-
|
|
97
|
-
if (options.debug) {
|
|
98
|
-
logger.wuDebug('🔧 Configuration updated:', this.defaultConfig)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return this
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 🐛 DEBUG MODE: Quick debug toggle
|
|
106
|
-
* wu.debug(true)
|
|
107
|
-
* wu.debug() // toggle
|
|
108
|
-
*/
|
|
109
|
-
debug(enabled) {
|
|
110
|
-
if (enabled === undefined) {
|
|
111
|
-
this.defaultConfig.debug = !this.defaultConfig.debug
|
|
112
|
-
} else {
|
|
113
|
-
this.defaultConfig.debug = !!enabled
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
logger.wuInfo(`🐛 Debug mode: ${this.defaultConfig.debug ? 'ON' : 'OFF'}`)
|
|
117
|
-
return this
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* ⏱️ TIMEOUT: Set operation timeout
|
|
122
|
-
* wu.timeout(60000) // 60 seconds
|
|
123
|
-
*/
|
|
124
|
-
timeout(ms) {
|
|
125
|
-
this.defaultConfig.timeout = ms
|
|
126
|
-
logger.wuDebug(`⏱️ Timeout set to ${ms}ms`)
|
|
127
|
-
return this
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 🔄 RETRIES: Set retry attempts
|
|
132
|
-
* wu.retries(5)
|
|
133
|
-
*/
|
|
134
|
-
retries(count) {
|
|
135
|
-
this.defaultConfig.retries = count
|
|
136
|
-
logger.wuDebug(`🔄 Retries set to ${count}`)
|
|
137
|
-
return this
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 🎯 DEFAULT CONTAINER: Set default mounting container
|
|
142
|
-
* wu.container('#main-app')
|
|
143
|
-
*/
|
|
144
|
-
container(selector) {
|
|
145
|
-
this.defaultConfig.container = selector
|
|
146
|
-
logger.wuDebug(`🎯 Default container set to ${selector}`)
|
|
147
|
-
return this
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* 🌐 GLOBAL SETTINGS: Environment-based configuration
|
|
152
|
-
* wu.development() // Sets debug: true, retries: 1
|
|
153
|
-
* wu.production() // Sets debug: false, retries: 3
|
|
154
|
-
*/
|
|
155
|
-
development() {
|
|
156
|
-
return this.config({
|
|
157
|
-
debug: true,
|
|
158
|
-
retries: 1,
|
|
159
|
-
timeout: 60000
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
production() {
|
|
164
|
-
return this.config({
|
|
165
|
-
debug: false,
|
|
166
|
-
retries: 3,
|
|
167
|
-
timeout: 30000
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 🚀 QUICK SETUP: Common configurations
|
|
173
|
-
* wu.spa() // Single Page App mode
|
|
174
|
-
* wu.micro() // Microfrontend mode
|
|
175
|
-
*/
|
|
176
|
-
spa() {
|
|
177
|
-
return this.config({
|
|
178
|
-
mode: 'spa',
|
|
179
|
-
container: '#app',
|
|
180
|
-
debug: false
|
|
181
|
-
})
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
micro() {
|
|
185
|
-
return this.config({
|
|
186
|
-
mode: 'microfrontend',
|
|
187
|
-
debug: true,
|
|
188
|
-
retries: 5
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* 📊 STATUS: Get framework and apps status
|
|
194
|
-
* wu.status()
|
|
195
|
-
*/
|
|
196
|
-
status() {
|
|
197
|
-
const stats = this.core.getStats?.() || {}
|
|
198
|
-
|
|
199
|
-
return {
|
|
200
|
-
initialized: this.autoInitialized,
|
|
201
|
-
apps: {
|
|
202
|
-
registered: stats.registered || 0,
|
|
203
|
-
mounted: stats.mounted || 0,
|
|
204
|
-
available: stats.apps || []
|
|
205
|
-
},
|
|
206
|
-
health: this.core.quantumState?.dimensionalStability || 'unknown',
|
|
207
|
-
config: this.defaultConfig
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* 🧹 CLEANUP: Clean shutdown
|
|
213
|
-
* wu.destroy()
|
|
214
|
-
*/
|
|
215
|
-
async destroy() {
|
|
216
|
-
if (this.core.destroy) {
|
|
217
|
-
await this.core.destroy()
|
|
218
|
-
}
|
|
219
|
-
this.autoInitialized = false
|
|
220
|
-
logger.wuInfo('🧹 Framework destroyed')
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// 🔒 PRIVATE METHODS
|
|
225
|
-
|
|
226
|
-
async _ensureInitialized() {
|
|
227
|
-
if (!this.autoInitialized) {
|
|
228
|
-
await this._autoInitialize()
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
async _autoInitialize() {
|
|
233
|
-
if (this.defaultConfig.debug) {
|
|
234
|
-
logger.wuDebug('🚀 Auto-initializing Wu Framework...')
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Smart initialization with minimal config
|
|
238
|
-
await this.core.init({ apps: [] })
|
|
239
|
-
this.autoInitialized = true
|
|
240
|
-
|
|
241
|
-
if (this.defaultConfig.debug) {
|
|
242
|
-
logger.wuDebug('✅ Wu Framework auto-initialized')
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
_isUrl(str) {
|
|
247
|
-
try {
|
|
248
|
-
new URL(str)
|
|
249
|
-
return true
|
|
250
|
-
} catch {
|
|
251
|
-
return str.includes('://') || str.startsWith('http')
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
_extractAppName(url) {
|
|
256
|
-
try {
|
|
257
|
-
const urlObj = new URL(url)
|
|
258
|
-
const pathSegments = urlObj.pathname.split('/').filter(Boolean)
|
|
259
|
-
return pathSegments[pathSegments.length - 1] || urlObj.hostname.split('.')[0]
|
|
260
|
-
} catch {
|
|
261
|
-
return 'app-' + Date.now()
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
async _registerFromUrl(url, appName) {
|
|
266
|
-
const baseUrl = this._getBaseUrl(url)
|
|
267
|
-
|
|
268
|
-
await this.core.registerApp({
|
|
269
|
-
name: appName,
|
|
270
|
-
url: baseUrl
|
|
271
|
-
})
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
_getBaseUrl(url) {
|
|
275
|
-
try {
|
|
276
|
-
const urlObj = new URL(url)
|
|
277
|
-
return `${urlObj.protocol}//${urlObj.host}`
|
|
278
|
-
} catch {
|
|
279
|
-
return url
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
async _mountFromUrl(url, containerSelector) {
|
|
284
|
-
const appName = this._extractAppName(url)
|
|
285
|
-
await this._registerFromUrl(url, appName)
|
|
286
|
-
return await this._mountFromName(appName, containerSelector)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async _mountFromName(appName, containerSelector) {
|
|
290
|
-
try {
|
|
291
|
-
await this.core.mount(appName, containerSelector)
|
|
292
|
-
|
|
293
|
-
if (this.defaultConfig.debug) {
|
|
294
|
-
logger.wuDebug(`✅ ${appName} mounted successfully in ${containerSelector}`)
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
return {
|
|
298
|
-
app: appName,
|
|
299
|
-
container: containerSelector,
|
|
300
|
-
status: 'mounted',
|
|
301
|
-
unmount: () => this.core.unmount(appName)
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
} catch (error) {
|
|
305
|
-
console.error(`[Wu] ❌ Failed to mount ${appName}:`, error.message)
|
|
306
|
-
throw new Error(`Failed to mount ${appName}: ${error.message}`)
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// 🌟 Create singleton instance
|
|
312
|
-
const wuSimple = new WuSimpleAPI()
|
|
313
|
-
|
|
314
|
-
// 🎯 Export simple API
|
|
315
|
-
export { wuSimple as wu }
|
|
316
|
-
export default wuSimple
|