wu-framework 1.1.17 → 1.1.19

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.
Files changed (42) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +460 -440
  3. package/integrations/astro/README.md +127 -127
  4. package/integrations/astro/WuApp.astro +63 -63
  5. package/integrations/astro/WuShell.astro +39 -39
  6. package/integrations/astro/index.js +68 -68
  7. package/integrations/astro/package.json +38 -38
  8. package/integrations/astro/types.d.ts +53 -53
  9. package/package.json +45 -2
  10. package/src/adapters/alpine/index.d.ts +60 -0
  11. package/src/adapters/alpine/index.js +231 -0
  12. package/src/adapters/alpine.d.ts +3 -0
  13. package/src/adapters/alpine.js +3 -0
  14. package/src/adapters/htmx/index.d.ts +60 -0
  15. package/src/adapters/htmx/index.js +242 -0
  16. package/src/adapters/htmx.d.ts +3 -0
  17. package/src/adapters/htmx.js +3 -0
  18. package/src/adapters/index.js +60 -3
  19. package/src/adapters/qwik/index.d.ts +52 -0
  20. package/src/adapters/qwik/index.js +50 -0
  21. package/src/adapters/qwik.d.ts +3 -0
  22. package/src/adapters/qwik.js +3 -0
  23. package/src/adapters/react/ai.js +135 -135
  24. package/src/adapters/react/index.d.ts +246 -246
  25. package/src/adapters/react/index.js +695 -695
  26. package/src/adapters/stencil/index.d.ts +54 -0
  27. package/src/adapters/stencil/index.js +228 -0
  28. package/src/adapters/stencil.d.ts +3 -0
  29. package/src/adapters/stencil.js +3 -0
  30. package/src/adapters/stimulus/index.d.ts +60 -0
  31. package/src/adapters/stimulus/index.js +255 -0
  32. package/src/adapters/stimulus.d.ts +3 -0
  33. package/src/adapters/stimulus.js +3 -0
  34. package/src/adapters/vue/index.js +8 -0
  35. package/dist/wu-framework.cjs.js +0 -3
  36. package/dist/wu-framework.cjs.js.map +0 -1
  37. package/dist/wu-framework.dev.js +0 -15667
  38. package/dist/wu-framework.dev.js.map +0 -1
  39. package/dist/wu-framework.esm.js +0 -3
  40. package/dist/wu-framework.esm.js.map +0 -1
  41. package/dist/wu-framework.umd.js +0 -3
  42. package/dist/wu-framework.umd.js.map +0 -1
@@ -0,0 +1,54 @@
1
+ /**
2
+ * WU-FRAMEWORK STENCIL ADAPTER - TypeScript Declarations
3
+ */
4
+
5
+ import type { WuCore } from '../../core/wu-core';
6
+
7
+ /**
8
+ * Stencil adapter registration options
9
+ */
10
+ export interface StencilRegisterOptions {
11
+ /** Properties to set on the custom element (rich data: objects, arrays, functions) */
12
+ props?: Record<string, any>;
13
+ /** HTML attributes to set on the custom element (string values) */
14
+ attributes?: Record<string, string>;
15
+ /** Callback after mounting */
16
+ onMount?: (container: HTMLElement) => void;
17
+ /** Callback before unmounting */
18
+ onUnmount?: (container: HTMLElement) => void;
19
+ /** Allow standalone execution when Wu Framework is not available */
20
+ standalone?: boolean;
21
+ /** CSS selector for standalone mode container */
22
+ standaloneContainer?: string;
23
+ }
24
+
25
+ /**
26
+ * Register a Stencil-compiled Web Component as a Wu microfrontend
27
+ */
28
+ export function register(
29
+ appName: string,
30
+ tagName: string,
31
+ options?: StencilRegisterOptions
32
+ ): Promise<boolean>;
33
+
34
+ /**
35
+ * Get the current Wu Framework instance
36
+ */
37
+ export function getWuInstance(): WuCore | null;
38
+
39
+ /**
40
+ * Wait for Wu Framework to become available
41
+ */
42
+ export function waitForWu(timeout?: number): Promise<WuCore>;
43
+
44
+ /**
45
+ * Stencil adapter interface
46
+ */
47
+ export interface WuStencilAdapter {
48
+ register: typeof register;
49
+ getWuInstance: typeof getWuInstance;
50
+ waitForWu: typeof waitForWu;
51
+ }
52
+
53
+ export const wuStencil: WuStencilAdapter;
54
+ export default wuStencil;
@@ -0,0 +1,228 @@
1
+ /**
2
+ * WU-FRAMEWORK STENCIL ADAPTER
3
+ *
4
+ * Integrates Stencil-compiled Web Components into Wu Framework.
5
+ * Stencil outputs standards-compliant Custom Elements, so this
6
+ * adapter's job is thin by design: create the element, append it,
7
+ * and let the browser's native lifecycle (connectedCallback /
8
+ * disconnectedCallback) do the heavy lifting. The adapter adds
9
+ * Wu's orchestration layer on top -- coordinated mount/unmount
10
+ * across the microfrontend graph, standalone fallback, and
11
+ * property forwarding.
12
+ *
13
+ * @example
14
+ * import { wuStencil } from 'wu-framework/adapters/stencil';
15
+ *
16
+ * wuStencil.register('my-component', 'my-stencil-component');
17
+ *
18
+ * @example
19
+ * // With properties
20
+ * wuStencil.register('user-profile', 'user-profile-card', {
21
+ * props: { userId: 42, theme: 'dark' },
22
+ * onMount: (container) => console.log('Stencil component connected')
23
+ * });
24
+ */
25
+
26
+ // Adapter-scoped state
27
+ const adapterState = {
28
+ apps: new Map()
29
+ };
30
+
31
+ /**
32
+ * Obtiene la instancia de Wu Framework
33
+ */
34
+ function getWuInstance() {
35
+ if (typeof window === 'undefined') return null;
36
+
37
+ return window.wu
38
+ || window.parent?.wu
39
+ || window.top?.wu
40
+ || null;
41
+ }
42
+
43
+ /**
44
+ * Espera a que Wu Framework este disponible
45
+ */
46
+ function waitForWu(timeout = 5000) {
47
+ return new Promise((resolve, reject) => {
48
+ const wu = getWuInstance();
49
+ if (wu) {
50
+ resolve(wu);
51
+ return;
52
+ }
53
+
54
+ const startTime = Date.now();
55
+
56
+ const handleWuReady = () => {
57
+ cleanup();
58
+ resolve(getWuInstance());
59
+ };
60
+
61
+ window.addEventListener('wu:ready', handleWuReady);
62
+ window.addEventListener('wu:app:ready', handleWuReady);
63
+
64
+ const checkInterval = setInterval(() => {
65
+ const wu = getWuInstance();
66
+ if (wu) {
67
+ cleanup();
68
+ resolve(wu);
69
+ return;
70
+ }
71
+
72
+ if (Date.now() - startTime > timeout) {
73
+ cleanup();
74
+ reject(new Error(`Wu Framework not found after ${timeout}ms`));
75
+ }
76
+ }, 200);
77
+
78
+ function cleanup() {
79
+ clearInterval(checkInterval);
80
+ window.removeEventListener('wu:ready', handleWuReady);
81
+ window.removeEventListener('wu:app:ready', handleWuReady);
82
+ }
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Registra un Web Component compilado con Stencil como microfrontend
88
+ *
89
+ * @param {string} appName - Nombre unico del microfrontend
90
+ * @param {string} tagName - Tag del Custom Element generado por Stencil
91
+ * @param {Object} [options] - Opciones adicionales
92
+ * @param {Object} [options.props={}] - Propiedades a setear en el elemento
93
+ * @param {Object} [options.attributes={}] - Atributos HTML a setear en el elemento
94
+ * @param {Function} [options.onMount] - Callback despues de montar
95
+ * @param {Function} [options.onUnmount] - Callback antes de desmontar
96
+ * @param {boolean} [options.standalone=true] - Permitir ejecucion standalone
97
+ * @param {string} [options.standaloneContainer='#app'] - Selector para modo standalone
98
+ * @returns {Promise<boolean>} true si el registro fue exitoso
99
+ */
100
+ async function register(appName, tagName, options = {}) {
101
+ const {
102
+ props = {},
103
+ attributes = {},
104
+ onMount = null,
105
+ onUnmount = null,
106
+ standalone = true,
107
+ standaloneContainer = '#app'
108
+ } = options;
109
+
110
+ if (!tagName || typeof tagName !== 'string') {
111
+ throw new Error(`[WuStencil] tagName (custom element tag) is required for ${appName}`);
112
+ }
113
+
114
+ // Mount function
115
+ const mountApp = (container) => {
116
+ if (!container) {
117
+ console.error(`[WuStencil] Mount failed for ${appName}: container is null`);
118
+ return;
119
+ }
120
+
121
+ // Prevent double-mount
122
+ if (adapterState.apps.has(appName)) {
123
+ console.warn(`[WuStencil] ${appName} already mounted, unmounting first`);
124
+ unmountApp();
125
+ }
126
+
127
+ try {
128
+ container.innerHTML = '';
129
+
130
+ // Create the Stencil web component element
131
+ const element = document.createElement(tagName);
132
+
133
+ // Forward properties (rich data: objects, arrays, functions)
134
+ for (const [key, value] of Object.entries(props)) {
135
+ element[key] = value;
136
+ }
137
+
138
+ // Set HTML attributes (strings only)
139
+ for (const [key, value] of Object.entries(attributes)) {
140
+ element.setAttribute(key, String(value));
141
+ }
142
+
143
+ container.appendChild(element);
144
+
145
+ adapterState.apps.set(appName, {
146
+ container,
147
+ element,
148
+ tagName
149
+ });
150
+
151
+ console.log(`[WuStencil] ${appName} (<${tagName}>) mounted successfully`);
152
+
153
+ if (onMount) {
154
+ onMount(container);
155
+ }
156
+ } catch (error) {
157
+ console.error(`[WuStencil] Mount error for ${appName}:`, error);
158
+ throw error;
159
+ }
160
+ };
161
+
162
+ // Unmount function -- Stencil components clean up via disconnectedCallback
163
+ const unmountApp = (container) => {
164
+ const appData = adapterState.apps.get(appName);
165
+
166
+ if (appData) {
167
+ try {
168
+ if (onUnmount) {
169
+ onUnmount(appData.container);
170
+ }
171
+
172
+ // Removing the element triggers Stencil's disconnectedCallback
173
+ if (appData.element && appData.element.parentNode) {
174
+ appData.element.remove();
175
+ }
176
+
177
+ appData.container.innerHTML = '';
178
+ adapterState.apps.delete(appName);
179
+
180
+ console.log(`[WuStencil] ${appName} (<${tagName}>) unmounted successfully`);
181
+ } catch (error) {
182
+ console.error(`[WuStencil] Unmount error for ${appName}:`, error);
183
+ }
184
+ }
185
+
186
+ if (container) {
187
+ container.innerHTML = '';
188
+ }
189
+ };
190
+
191
+ // Register with Wu Framework or fall back to standalone
192
+ try {
193
+ const wu = await waitForWu(3000);
194
+
195
+ wu.define(appName, {
196
+ mount: mountApp,
197
+ unmount: unmountApp
198
+ });
199
+
200
+ console.log(`[WuStencil] ${appName} registered with Wu Framework`);
201
+ return true;
202
+
203
+ } catch (error) {
204
+ console.warn(`[WuStencil] Wu Framework not available for ${appName}`);
205
+
206
+ if (standalone) {
207
+ const containerElement = document.querySelector(standaloneContainer);
208
+
209
+ if (containerElement) {
210
+ console.log(`[WuStencil] Running ${appName} in standalone mode`);
211
+ mountApp(containerElement);
212
+ return true;
213
+ }
214
+ }
215
+
216
+ return false;
217
+ }
218
+ }
219
+
220
+ // Public API
221
+ export const wuStencil = {
222
+ register,
223
+ getWuInstance,
224
+ waitForWu
225
+ };
226
+
227
+ export { register, getWuInstance, waitForWu };
228
+ export default wuStencil;
@@ -0,0 +1,3 @@
1
+ // Re-export from folder structure — backward compatibility
2
+ export * from './stencil/index';
3
+ export { default } from './stencil/index';
@@ -0,0 +1,3 @@
1
+ // Re-export from folder structure — backward compatibility
2
+ export * from './stencil/index.js';
3
+ export { default } from './stencil/index.js';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * WU-FRAMEWORK STIMULUS ADAPTER - TypeScript Declarations
3
+ */
4
+
5
+ import type { WuCore } from '../../core/wu-core';
6
+
7
+ /**
8
+ * Stimulus app configuration
9
+ */
10
+ export interface StimulusAppConfig {
11
+ /** Map of controller name to Controller class */
12
+ controllers: Record<string, any>;
13
+ /** HTML template string containing data-controller and data-action attributes */
14
+ template: string;
15
+ }
16
+
17
+ /**
18
+ * Stimulus adapter registration options
19
+ */
20
+ export interface StimulusRegisterOptions {
21
+ /** Callback after mounting */
22
+ onMount?: (container: HTMLElement) => void;
23
+ /** Callback before unmounting */
24
+ onUnmount?: (container: HTMLElement) => void;
25
+ /** Allow standalone execution when Wu Framework is not available */
26
+ standalone?: boolean;
27
+ /** CSS selector for standalone mode container */
28
+ standaloneContainer?: string;
29
+ }
30
+
31
+ /**
32
+ * Register a Stimulus app as a Wu microfrontend
33
+ */
34
+ export function register(
35
+ appName: string,
36
+ config: StimulusAppConfig,
37
+ options?: StimulusRegisterOptions
38
+ ): Promise<boolean>;
39
+
40
+ /**
41
+ * Get the current Wu Framework instance
42
+ */
43
+ export function getWuInstance(): WuCore | null;
44
+
45
+ /**
46
+ * Wait for Wu Framework to become available
47
+ */
48
+ export function waitForWu(timeout?: number): Promise<WuCore>;
49
+
50
+ /**
51
+ * Stimulus adapter interface
52
+ */
53
+ export interface WuStimulusAdapter {
54
+ register: typeof register;
55
+ getWuInstance: typeof getWuInstance;
56
+ waitForWu: typeof waitForWu;
57
+ }
58
+
59
+ export const wuStimulus: WuStimulusAdapter;
60
+ export default wuStimulus;
@@ -0,0 +1,255 @@
1
+ /**
2
+ * WU-FRAMEWORK STIMULUS ADAPTER
3
+ *
4
+ * Integrates Hotwire Stimulus controllers into Wu Framework's
5
+ * microfrontend orchestration. Stimulus is the "modest JavaScript
6
+ * framework" -- it enhances server-rendered HTML with controllers
7
+ * that respond to DOM mutations via data-controller attributes.
8
+ *
9
+ * This adapter creates a scoped Stimulus Application instance per
10
+ * microfrontend, registers the provided controllers, injects the
11
+ * HTML template, and tears everything down cleanly on unmount.
12
+ *
13
+ * @example
14
+ * import { wuStimulus } from 'wu-framework/adapters/stimulus';
15
+ * import { Controller } from '@hotwired/stimulus';
16
+ *
17
+ * class GreetingController extends Controller {
18
+ * static targets = ['output'];
19
+ * greet() { this.outputTarget.textContent = 'Hello!'; }
20
+ * }
21
+ *
22
+ * wuStimulus.register('greeting-app', {
23
+ * controllers: { greeting: GreetingController },
24
+ * template: `
25
+ * <div data-controller="greeting">
26
+ * <button data-action="click->greeting#greet">Greet</button>
27
+ * <span data-greeting-target="output"></span>
28
+ * </div>
29
+ * `
30
+ * });
31
+ *
32
+ * @example
33
+ * // Multiple controllers
34
+ * wuStimulus.register('dashboard', {
35
+ * controllers: {
36
+ * tabs: TabsController,
37
+ * chart: ChartController,
38
+ * filter: FilterController
39
+ * },
40
+ * template: dashboardHTML
41
+ * }, {
42
+ * onMount: (container) => console.log('Stimulus controllers active')
43
+ * });
44
+ */
45
+
46
+ // Adapter-scoped state
47
+ const adapterState = {
48
+ apps: new Map()
49
+ };
50
+
51
+ /**
52
+ * Obtiene la instancia de Wu Framework
53
+ */
54
+ function getWuInstance() {
55
+ if (typeof window === 'undefined') return null;
56
+
57
+ return window.wu
58
+ || window.parent?.wu
59
+ || window.top?.wu
60
+ || null;
61
+ }
62
+
63
+ /**
64
+ * Espera a que Wu Framework este disponible
65
+ */
66
+ function waitForWu(timeout = 5000) {
67
+ return new Promise((resolve, reject) => {
68
+ const wu = getWuInstance();
69
+ if (wu) {
70
+ resolve(wu);
71
+ return;
72
+ }
73
+
74
+ const startTime = Date.now();
75
+
76
+ const handleWuReady = () => {
77
+ cleanup();
78
+ resolve(getWuInstance());
79
+ };
80
+
81
+ window.addEventListener('wu:ready', handleWuReady);
82
+ window.addEventListener('wu:app:ready', handleWuReady);
83
+
84
+ const checkInterval = setInterval(() => {
85
+ const wu = getWuInstance();
86
+ if (wu) {
87
+ cleanup();
88
+ resolve(wu);
89
+ return;
90
+ }
91
+
92
+ if (Date.now() - startTime > timeout) {
93
+ cleanup();
94
+ reject(new Error(`Wu Framework not found after ${timeout}ms`));
95
+ }
96
+ }, 200);
97
+
98
+ function cleanup() {
99
+ clearInterval(checkInterval);
100
+ window.removeEventListener('wu:ready', handleWuReady);
101
+ window.removeEventListener('wu:app:ready', handleWuReady);
102
+ }
103
+ });
104
+ }
105
+
106
+ /**
107
+ * Registra una app Stimulus como microfrontend
108
+ *
109
+ * @param {string} appName - Nombre unico del microfrontend
110
+ * @param {Object} config - Configuracion de la app Stimulus
111
+ * @param {Object} config.controllers - Map de nombre -> Controller class
112
+ * @param {string} config.template - HTML string con data-controller / data-action attributes
113
+ * @param {Object} [options] - Opciones adicionales
114
+ * @param {Function} [options.onMount] - Callback despues de montar
115
+ * @param {Function} [options.onUnmount] - Callback antes de desmontar
116
+ * @param {boolean} [options.standalone=true] - Permitir ejecucion standalone
117
+ * @param {string} [options.standaloneContainer='#app'] - Selector para modo standalone
118
+ * @returns {Promise<boolean>} true si el registro fue exitoso
119
+ */
120
+ async function register(appName, config, options = {}) {
121
+ const { controllers = {}, template } = config;
122
+
123
+ const {
124
+ onMount = null,
125
+ onUnmount = null,
126
+ standalone = true,
127
+ standaloneContainer = '#app'
128
+ } = options;
129
+
130
+ if (!template || typeof template !== 'string') {
131
+ throw new Error(`[WuStimulus] template (HTML string) is required for ${appName}`);
132
+ }
133
+
134
+ if (!controllers || typeof controllers !== 'object' || Object.keys(controllers).length === 0) {
135
+ throw new Error(`[WuStimulus] controllers (object of name -> Controller class) is required for ${appName}`);
136
+ }
137
+
138
+ // Mount function
139
+ const mountApp = (container) => {
140
+ if (!container) {
141
+ console.error(`[WuStimulus] Mount failed for ${appName}: container is null`);
142
+ return;
143
+ }
144
+
145
+ // Prevent double-mount
146
+ if (adapterState.apps.has(appName)) {
147
+ console.warn(`[WuStimulus] ${appName} already mounted, unmounting first`);
148
+ unmountApp();
149
+ }
150
+
151
+ try {
152
+ container.innerHTML = '';
153
+
154
+ // Dynamic import keeps Stimulus out of the critical path
155
+ import('@hotwired/stimulus').then(({ Application }) => {
156
+ // Create a scoped Stimulus Application for this microfrontend
157
+ const application = Application.start(container);
158
+
159
+ // Register all controllers
160
+ for (const [name, ControllerClass] of Object.entries(controllers)) {
161
+ application.register(name, ControllerClass);
162
+ }
163
+
164
+ // Inject template -- Stimulus will auto-connect controllers
165
+ // via MutationObserver watching data-controller attributes
166
+ container.innerHTML = template;
167
+
168
+ adapterState.apps.set(appName, {
169
+ container,
170
+ config,
171
+ application
172
+ });
173
+
174
+ console.log(`[WuStimulus] ${appName} mounted successfully (${Object.keys(controllers).length} controllers)`);
175
+
176
+ if (onMount) {
177
+ onMount(container);
178
+ }
179
+ }).catch((err) => {
180
+ console.error(`[WuStimulus] Failed to import @hotwired/stimulus for ${appName}:`, err);
181
+ container.innerHTML = `<div style="color:#721c24;padding:1rem;">Failed to load Stimulus runtime</div>`;
182
+ });
183
+ } catch (error) {
184
+ console.error(`[WuStimulus] Mount error for ${appName}:`, error);
185
+ throw error;
186
+ }
187
+ };
188
+
189
+ // Unmount function
190
+ const unmountApp = (container) => {
191
+ const appData = adapterState.apps.get(appName);
192
+
193
+ if (appData) {
194
+ try {
195
+ if (onUnmount) {
196
+ onUnmount(appData.container);
197
+ }
198
+
199
+ // Stop the scoped Stimulus Application
200
+ if (appData.application && typeof appData.application.stop === 'function') {
201
+ appData.application.stop();
202
+ }
203
+
204
+ appData.container.innerHTML = '';
205
+ adapterState.apps.delete(appName);
206
+
207
+ console.log(`[WuStimulus] ${appName} unmounted successfully`);
208
+ } catch (error) {
209
+ console.error(`[WuStimulus] Unmount error for ${appName}:`, error);
210
+ }
211
+ }
212
+
213
+ if (container) {
214
+ container.innerHTML = '';
215
+ }
216
+ };
217
+
218
+ // Register with Wu Framework or fall back to standalone
219
+ try {
220
+ const wu = await waitForWu(3000);
221
+
222
+ wu.define(appName, {
223
+ mount: mountApp,
224
+ unmount: unmountApp
225
+ });
226
+
227
+ console.log(`[WuStimulus] ${appName} registered with Wu Framework`);
228
+ return true;
229
+
230
+ } catch (error) {
231
+ console.warn(`[WuStimulus] Wu Framework not available for ${appName}`);
232
+
233
+ if (standalone) {
234
+ const containerElement = document.querySelector(standaloneContainer);
235
+
236
+ if (containerElement) {
237
+ console.log(`[WuStimulus] Running ${appName} in standalone mode`);
238
+ mountApp(containerElement);
239
+ return true;
240
+ }
241
+ }
242
+
243
+ return false;
244
+ }
245
+ }
246
+
247
+ // Public API
248
+ export const wuStimulus = {
249
+ register,
250
+ getWuInstance,
251
+ waitForWu
252
+ };
253
+
254
+ export { register, getWuInstance, waitForWu };
255
+ export default wuStimulus;
@@ -0,0 +1,3 @@
1
+ // Re-export from folder structure — backward compatibility
2
+ export * from './stimulus/index';
3
+ export { default } from './stimulus/index';
@@ -0,0 +1,3 @@
1
+ // Re-export from folder structure — backward compatibility
2
+ export * from './stimulus/index.js';
3
+ export { default } from './stimulus/index.js';
@@ -190,6 +190,14 @@ async function register(appName, RootComponent, options = {}) {
190
190
  setup(app);
191
191
  }
192
192
 
193
+ // Error handlers for debugging
194
+ app.config.errorHandler = (err, instance, info) => {
195
+ console.error(`[WuVue] ${appName} error in ${info}:`, err);
196
+ };
197
+ app.config.warnHandler = (msg, instance, trace) => {
198
+ console.warn(`[WuVue] ${appName} warn:`, msg);
199
+ };
200
+
193
201
  // Proveer información del contexto Wu
194
202
  app.provide('wuAppName', appName);
195
203
  app.provide('wuInstance', getWuInstance());