wu-framework 1.1.16 → 1.1.18
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 +52 -20
- package/package.json +48 -3
- package/src/adapters/alpine/index.d.ts +60 -0
- package/src/adapters/alpine/index.js +231 -0
- package/src/adapters/alpine.d.ts +3 -0
- package/src/adapters/alpine.js +3 -0
- package/src/adapters/htmx/index.d.ts +60 -0
- package/src/adapters/htmx/index.js +242 -0
- package/src/adapters/htmx.d.ts +3 -0
- package/src/adapters/htmx.js +3 -0
- package/src/adapters/index.js +60 -3
- package/src/adapters/qwik/index.d.ts +52 -0
- package/src/adapters/qwik/index.js +214 -0
- package/src/adapters/qwik.d.ts +3 -0
- package/src/adapters/qwik.js +3 -0
- package/src/adapters/react/ai.js +135 -135
- package/src/adapters/react/index.d.ts +246 -246
- package/src/adapters/react/index.js +695 -695
- package/src/adapters/stencil/index.d.ts +54 -0
- package/src/adapters/stencil/index.js +228 -0
- package/src/adapters/stencil.d.ts +3 -0
- package/src/adapters/stencil.js +3 -0
- package/src/adapters/stimulus/index.d.ts +60 -0
- package/src/adapters/stimulus/index.js +255 -0
- package/src/adapters/stimulus.d.ts +3 -0
- package/src/adapters/stimulus.js +3 -0
- package/src/adapters/svelte/index.js +1 -1
- package/src/adapters/vanilla/index.js +1 -1
- package/src/adapters/vue/index.js +8 -0
- package/src/core/wu-cache.js +24 -3
- package/src/core/wu-core.js +15 -1
- package/src/core/wu-error-boundary.js +17 -3
- package/src/core/wu-event-bus.js +43 -1
- package/src/core/wu-html-parser.js +13 -4
- package/src/core/wu-loader.js +162 -50
- package/src/core/wu-logger.js +21 -13
- package/src/core/wu-manifest.js +23 -0
- package/src/core/wu-plugin.js +57 -4
- package/src/core/wu-proxy-sandbox.js +2 -1
- package/src/core/wu-script-executor.js +48 -0
- package/src/core/wu-store.js +13 -3
- package/src/index.d.ts +317 -0
- package/src/index.js +11 -1
- package/dist/wu-framework.cjs.js +0 -3
- package/dist/wu-framework.cjs.js.map +0 -1
- package/dist/wu-framework.dev.js +0 -15302
- package/dist/wu-framework.dev.js.map +0 -1
- package/dist/wu-framework.esm.js +0 -3
- package/dist/wu-framework.esm.js.map +0 -1
- package/dist/wu-framework.umd.js +0 -3
- package/dist/wu-framework.umd.js.map +0 -1
package/src/core/wu-plugin.js
CHANGED
|
@@ -11,7 +11,7 @@ import { logger } from './wu-logger.js';
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
export class WuPluginSystem {
|
|
14
|
-
constructor(core) {
|
|
14
|
+
constructor(core, options = {}) {
|
|
15
15
|
this._core = core; // Privado - no expuesto a plugins
|
|
16
16
|
this.plugins = new Map();
|
|
17
17
|
this.hooks = new Map();
|
|
@@ -35,7 +35,7 @@ export class WuPluginSystem {
|
|
|
35
35
|
];
|
|
36
36
|
|
|
37
37
|
// 🔐 Timeout para hooks (evita que plugins bloqueen)
|
|
38
|
-
this.hookTimeout = 5000; // 5 segundos
|
|
38
|
+
this.hookTimeout = options.hookTimeout || 5000; // Default: 5 segundos
|
|
39
39
|
|
|
40
40
|
this.availableHooks.forEach(hook => {
|
|
41
41
|
this.hooks.set(hook, []);
|
|
@@ -106,8 +106,61 @@ export class WuPluginSystem {
|
|
|
106
106
|
logger.warn('[WuPlugin] ⚠️ Plugin has unsafe access to core!');
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// Congelar API para evitar modificaciones
|
|
110
|
-
return
|
|
109
|
+
// Congelar API recursivamente para evitar modificaciones en cualquier nivel
|
|
110
|
+
return WuPluginSystem._deepFreeze(api);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Deep-freeze an object and all its nested plain objects and arrays.
|
|
115
|
+
* Functions, DOM nodes, and other non-plain types are left untouched
|
|
116
|
+
* so they remain callable / functional. A WeakSet guards against
|
|
117
|
+
* circular references.
|
|
118
|
+
*
|
|
119
|
+
* @param {*} obj - The value to deep-freeze
|
|
120
|
+
* @param {WeakSet} [seen] - Internal tracker for circular references
|
|
121
|
+
* @returns {*} The same object, now deeply frozen
|
|
122
|
+
*/
|
|
123
|
+
static _deepFreeze(obj, seen) {
|
|
124
|
+
if (obj === null || obj === undefined) {
|
|
125
|
+
return obj;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Only freeze plain objects and arrays.
|
|
129
|
+
// Functions must stay invocable; DOM nodes, class instances, etc.
|
|
130
|
+
// should not be tampered with.
|
|
131
|
+
const dominated = typeof obj === 'object';
|
|
132
|
+
if (!dominated) {
|
|
133
|
+
return obj;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const isPlainObject =
|
|
137
|
+
Object.getPrototypeOf(obj) === Object.prototype ||
|
|
138
|
+
Object.getPrototypeOf(obj) === null;
|
|
139
|
+
const isArray = Array.isArray(obj);
|
|
140
|
+
|
|
141
|
+
if (!isPlainObject && !isArray) {
|
|
142
|
+
return obj;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Circular-reference guard
|
|
146
|
+
if (!seen) {
|
|
147
|
+
seen = new WeakSet();
|
|
148
|
+
}
|
|
149
|
+
if (seen.has(obj)) {
|
|
150
|
+
return obj;
|
|
151
|
+
}
|
|
152
|
+
seen.add(obj);
|
|
153
|
+
|
|
154
|
+
// Recurse into own enumerable properties
|
|
155
|
+
const keys = Object.keys(obj);
|
|
156
|
+
for (let i = 0; i < keys.length; i++) {
|
|
157
|
+
const value = obj[keys[i]];
|
|
158
|
+
if (value !== null && value !== undefined && typeof value === 'object') {
|
|
159
|
+
WuPluginSystem._deepFreeze(value, seen);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return Object.freeze(obj);
|
|
111
164
|
}
|
|
112
165
|
|
|
113
166
|
/**
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
import { logger } from './wu-logger.js';
|
|
14
14
|
|
|
15
15
|
export class WuProxySandbox {
|
|
16
|
-
constructor(appName) {
|
|
16
|
+
constructor(appName, options = {}) {
|
|
17
17
|
this.appName = appName;
|
|
18
|
+
this.options = options;
|
|
18
19
|
this.proxy = null;
|
|
19
20
|
this.fakeWindow = Object.create(null);
|
|
20
21
|
this.active = false;
|
|
@@ -15,6 +15,52 @@ import { logger } from './wu-logger.js';
|
|
|
15
15
|
|
|
16
16
|
export class WuScriptExecutor {
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Dangerous patterns that indicate prototype pollution, sandbox escape,
|
|
20
|
+
* or direct access to sensitive APIs. Each entry is a regex paired with
|
|
21
|
+
* a human-readable label used in error messages.
|
|
22
|
+
*
|
|
23
|
+
* This is a tripwire, not a full parser. It catches the most common
|
|
24
|
+
* attack vectors without the overhead of AST analysis.
|
|
25
|
+
*/
|
|
26
|
+
static DANGEROUS_PATTERNS = [
|
|
27
|
+
// Prototype pollution vectors
|
|
28
|
+
{ pattern: /constructor\s*\[\s*['"`]constructor['"`]\s*\]/, label: 'constructor chain access (sandbox escape)' },
|
|
29
|
+
{ pattern: /__proto__/, label: '__proto__ access (prototype pollution)' },
|
|
30
|
+
|
|
31
|
+
// Sandbox escape via proxy introspection
|
|
32
|
+
{ pattern: /Object\s*\.\s*getPrototypeOf\s*\(\s*proxy\s*\)/, label: 'Object.getPrototypeOf(proxy) (sandbox escape)' },
|
|
33
|
+
|
|
34
|
+
// Dynamic code generation that bypasses the sandbox
|
|
35
|
+
{ pattern: /Function\s*\(\s*['"`]/, label: 'Function() constructor (dynamic code generation)' },
|
|
36
|
+
{ pattern: /\beval\s*\(/, label: 'eval() (dynamic code execution)' },
|
|
37
|
+
|
|
38
|
+
// Dynamic import escapes the sandbox entirely (runs in global scope)
|
|
39
|
+
{ pattern: /\bimport\s*\(/, label: 'import() (dynamic import escapes sandbox)' },
|
|
40
|
+
|
|
41
|
+
// Direct cookie access (should go through proxy traps, not raw document)
|
|
42
|
+
{ pattern: /document\s*\.\s*cookie/, label: 'document.cookie (direct cookie access)' },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Validate script text against known dangerous patterns before execution.
|
|
47
|
+
* Throws if any pattern matches. This is intentionally lightweight --
|
|
48
|
+
* pattern detection only, not a full parse.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} scriptText - The raw script to validate
|
|
51
|
+
* @param {string} appName - App identifier (for error context)
|
|
52
|
+
* @throws {Error} If a dangerous pattern is detected
|
|
53
|
+
*/
|
|
54
|
+
_validateScript(scriptText, appName) {
|
|
55
|
+
for (const { pattern, label } of WuScriptExecutor.DANGEROUS_PATTERNS) {
|
|
56
|
+
if (pattern.test(scriptText)) {
|
|
57
|
+
const msg = `[ScriptExecutor] Blocked dangerous pattern in "${appName}": ${label}`;
|
|
58
|
+
logger.wuError(msg);
|
|
59
|
+
throw new Error(msg);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
18
64
|
/**
|
|
19
65
|
* Execute a script string inside the proxy sandbox.
|
|
20
66
|
*
|
|
@@ -31,6 +77,8 @@ export class WuScriptExecutor {
|
|
|
31
77
|
|
|
32
78
|
if (!scriptText || !scriptText.trim()) return;
|
|
33
79
|
|
|
80
|
+
this._validateScript(scriptText, appName);
|
|
81
|
+
|
|
34
82
|
const sourceComment = sourceUrl ? `\n//# sourceURL=wu-sandbox:///${appName}/${sourceUrl}\n` : '';
|
|
35
83
|
|
|
36
84
|
let wrappedCode;
|
package/src/core/wu-store.js
CHANGED
|
@@ -8,6 +8,15 @@
|
|
|
8
8
|
* - API minimalista: get(), set(), on()
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} WuStoreMetrics
|
|
13
|
+
* @property {number} reads - Total read operations
|
|
14
|
+
* @property {number} writes - Total write operations
|
|
15
|
+
* @property {number} notifications - Total notifications sent
|
|
16
|
+
* @property {number} bufferUtilization - Ring buffer utilization (0-1)
|
|
17
|
+
* @property {number} listenerCount - Active listener count
|
|
18
|
+
*/
|
|
19
|
+
|
|
11
20
|
export class WuStore {
|
|
12
21
|
constructor(bufferSize = 256) {
|
|
13
22
|
// Ring Buffer configuration
|
|
@@ -63,8 +72,9 @@ export class WuStore {
|
|
|
63
72
|
set(path, value) {
|
|
64
73
|
this.metrics.writes++;
|
|
65
74
|
|
|
66
|
-
// Write to ring buffer (lock-free)
|
|
67
|
-
const sequence = this.cursor
|
|
75
|
+
// Write to ring buffer (lock-free, wraps at buffer boundary)
|
|
76
|
+
const sequence = this.cursor;
|
|
77
|
+
this.cursor = (this.cursor + 1) % (this.bufferSize * this.bufferSize);
|
|
68
78
|
const index = sequence & this.mask;
|
|
69
79
|
|
|
70
80
|
// Reuse buffer slot (zero allocation)
|
|
@@ -151,7 +161,7 @@ export class WuStore {
|
|
|
151
161
|
getMetrics() {
|
|
152
162
|
return {
|
|
153
163
|
...this.metrics,
|
|
154
|
-
bufferUtilization: (this.cursor
|
|
164
|
+
bufferUtilization: Math.min(1, this.cursor / this.bufferSize),
|
|
155
165
|
listenerCount: this.listeners.size + this.patternListeners.size
|
|
156
166
|
};
|
|
157
167
|
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
// Wu Framework - Type Declarations
|
|
2
|
+
|
|
3
|
+
// --- Core Types ---
|
|
4
|
+
|
|
5
|
+
export interface WuEvent {
|
|
6
|
+
name: string;
|
|
7
|
+
data: any;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
appName: string;
|
|
10
|
+
meta: Record<string, any>;
|
|
11
|
+
verified: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WuAppConfig {
|
|
15
|
+
name: string;
|
|
16
|
+
url: string;
|
|
17
|
+
container?: string;
|
|
18
|
+
keepAlive?: boolean;
|
|
19
|
+
sandbox?: 'module' | 'strict' | 'eval';
|
|
20
|
+
styleMode?: 'shared' | 'isolated' | 'fully-isolated';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface WuLifecycle {
|
|
24
|
+
mount: (container: HTMLElement) => void | Promise<void>;
|
|
25
|
+
unmount?: (container: HTMLElement) => void | Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface WuPlugin {
|
|
29
|
+
name: string;
|
|
30
|
+
permissions?: Array<'mount' | 'events' | 'store' | 'apps' | 'config' | 'unsafe'>;
|
|
31
|
+
install?: (api: WuSandboxedApi, options?: any) => void;
|
|
32
|
+
uninstall?: (api: WuSandboxedApi) => void;
|
|
33
|
+
beforeInit?: (context: any) => void | Promise<void>;
|
|
34
|
+
afterInit?: (context: any) => void | Promise<void>;
|
|
35
|
+
beforeMount?: (context: any) => void | boolean | Promise<void | boolean>;
|
|
36
|
+
afterMount?: (context: any) => void | Promise<void>;
|
|
37
|
+
beforeUnmount?: (context: any) => void | Promise<void>;
|
|
38
|
+
afterUnmount?: (context: any) => void | Promise<void>;
|
|
39
|
+
onError?: (context: any) => void | Promise<void>;
|
|
40
|
+
onDestroy?: (context: any) => void | Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface WuSandboxedApi {
|
|
44
|
+
version: string;
|
|
45
|
+
info: { name: string; description: string; features: string[] };
|
|
46
|
+
getAppInfo(appName: string): { name: string; state: string; timestamp: number } | null;
|
|
47
|
+
getMountedApps(): string[];
|
|
48
|
+
getStats(): Record<string, any>;
|
|
49
|
+
emit?(event: string, data: any): boolean;
|
|
50
|
+
on?(event: string, cb: (event: WuEvent) => void): () => void;
|
|
51
|
+
off?(event: string, cb: (event: WuEvent) => void): void;
|
|
52
|
+
getState?(path: string): any;
|
|
53
|
+
setState?(path: string, value: any): number;
|
|
54
|
+
mount?(appName: string, container: string): Promise<void>;
|
|
55
|
+
unmount?(appName: string): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// --- Core Classes ---
|
|
59
|
+
|
|
60
|
+
export class WuCore {
|
|
61
|
+
apps: Map<string, any>;
|
|
62
|
+
mounted: Map<string, any>;
|
|
63
|
+
eventBus: WuEventBus;
|
|
64
|
+
store: WuStore;
|
|
65
|
+
pluginSystem: WuPluginSystem;
|
|
66
|
+
hooks: WuLifecycleHooks;
|
|
67
|
+
performance: WuPerformance;
|
|
68
|
+
|
|
69
|
+
init(config: { apps: WuAppConfig[]; sandbox?: string; overrides?: any }): Promise<void>;
|
|
70
|
+
mount(appName: string, containerSelector: string): Promise<void>;
|
|
71
|
+
unmount(appName: string, options?: { force?: boolean; defer?: boolean }): Promise<void>;
|
|
72
|
+
define(appName: string, lifecycle: WuLifecycle): void;
|
|
73
|
+
app(name: string, config: Partial<WuAppConfig>): WuApp;
|
|
74
|
+
hide(appName: string): Promise<void>;
|
|
75
|
+
show(appName: string): Promise<void>;
|
|
76
|
+
isHidden(appName: string): boolean;
|
|
77
|
+
destroy(): void;
|
|
78
|
+
getStats(): Record<string, any>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export class WuEventBus {
|
|
82
|
+
constructor();
|
|
83
|
+
emit(eventName: string, data?: any, options?: { appName?: string; token?: string; meta?: any }): boolean;
|
|
84
|
+
on(eventName: string, callback: (event: WuEvent) => void): () => void;
|
|
85
|
+
once(eventName: string, callback: (event: WuEvent) => void): () => void;
|
|
86
|
+
off(eventName: string, callback: (event: WuEvent) => void): void;
|
|
87
|
+
registerApp(appName: string, options?: { permissions?: string[]; token?: string }): string;
|
|
88
|
+
unregisterApp(appName: string): void;
|
|
89
|
+
replay(eventNameOrPattern: string, callback: (event: WuEvent) => void): void;
|
|
90
|
+
enableStrictMode(): void;
|
|
91
|
+
disableStrictMode(): void;
|
|
92
|
+
removeAll(): void;
|
|
93
|
+
getStats(): Record<string, any>;
|
|
94
|
+
configure(config: Partial<Record<string, any>>): void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class WuStore {
|
|
98
|
+
constructor(bufferSize?: number);
|
|
99
|
+
get(path?: string): any;
|
|
100
|
+
set(path: string, value: any): number;
|
|
101
|
+
on(pattern: string, callback: (value: any, path?: string) => void): () => void;
|
|
102
|
+
batch(updates: Record<string, any>): number[];
|
|
103
|
+
clear(): void;
|
|
104
|
+
getMetrics(): { reads: number; writes: number; notifications: number; bufferUtilization: number; listenerCount: number };
|
|
105
|
+
getRecentEvents(count?: number): Array<{ path: string; value: any; timestamp: number }>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export class WuLoader {
|
|
109
|
+
constructor(options?: { maxCacheSize?: number; cacheTTL?: number });
|
|
110
|
+
loadApp(appUrl: string, manifest?: any): Promise<string>;
|
|
111
|
+
loadComponent(appUrl: string, componentPath: string): Promise<any>;
|
|
112
|
+
preload(appConfigs: WuAppConfig[]): Promise<void>;
|
|
113
|
+
isAvailable(url: string): Promise<boolean>;
|
|
114
|
+
clearCache(pattern?: string): void;
|
|
115
|
+
getStats(): Record<string, any>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export class WuSandbox {
|
|
119
|
+
create(appName: string, container: HTMLElement, options?: any): any;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export class WuManifest {
|
|
123
|
+
load(appUrl: string): Promise<any>;
|
|
124
|
+
validate(manifest: any): any;
|
|
125
|
+
create(name: string, config?: any): any;
|
|
126
|
+
clearCache(pattern?: string): void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export class WuApp {
|
|
130
|
+
mount(): Promise<void>;
|
|
131
|
+
unmount(): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export class WuCache {
|
|
135
|
+
constructor(options?: { maxSize?: number; maxItems?: number; defaultTTL?: number; persistent?: boolean; storage?: string });
|
|
136
|
+
get(key: string): any;
|
|
137
|
+
set(key: string, value: any, ttl?: number): boolean;
|
|
138
|
+
delete(key: string): void;
|
|
139
|
+
clear(): void;
|
|
140
|
+
getStats(): Record<string, any>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export class WuPerformance {
|
|
144
|
+
startMeasure(name: string, appName?: string): void;
|
|
145
|
+
endMeasure(name: string, appName?: string): number;
|
|
146
|
+
generateReport(): Record<string, any>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export class WuProxySandbox {
|
|
150
|
+
constructor(appName: string, options?: Record<string, any>);
|
|
151
|
+
activate(): any;
|
|
152
|
+
deactivate(): void;
|
|
153
|
+
patchWindow(): void;
|
|
154
|
+
unpatchWindow(): void;
|
|
155
|
+
setContainer(container: HTMLElement, shadowRoot: ShadowRoot): void;
|
|
156
|
+
getProxy(): any;
|
|
157
|
+
isActive(): boolean;
|
|
158
|
+
getStats(): Record<string, any>;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export class WuSnapshotSandbox {
|
|
162
|
+
constructor(appName: string);
|
|
163
|
+
activate(): void;
|
|
164
|
+
deactivate(): void;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export class WuHtmlParser {
|
|
168
|
+
parse(html: string, appName: string, baseUrl: string): { dom: string; scripts: { inline: string[]; external: string[] }; styles: { inline: string[]; external: string[] } };
|
|
169
|
+
fetchHtml(url: string, appName: string): Promise<string>;
|
|
170
|
+
fetchAndParse(url: string, appName: string): Promise<any>;
|
|
171
|
+
clearCache(): void;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export class WuScriptExecutor {
|
|
175
|
+
execute(scriptText: string, appName: string, proxy: any, options?: { strictGlobal?: boolean; sourceUrl?: string }): any;
|
|
176
|
+
fetchScript(url: string): Promise<string>;
|
|
177
|
+
executeAll(scripts: Array<{ content?: string; src?: string }>, appName: string, proxy: any, options?: any): Promise<void>;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export class WuIframeSandbox {
|
|
181
|
+
constructor();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export class WuPluginSystem {
|
|
185
|
+
constructor(core: WuCore, options?: { hookTimeout?: number });
|
|
186
|
+
use(plugin: WuPlugin | ((options?: any) => WuPlugin), options?: any): void;
|
|
187
|
+
uninstall(pluginName: string): void;
|
|
188
|
+
getPlugin(pluginName: string): WuPlugin | undefined;
|
|
189
|
+
getStats(): Record<string, any>;
|
|
190
|
+
cleanup(): void;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export class WuLoadingStrategy {
|
|
194
|
+
constructor(core: WuCore);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export class WuPrefetch {
|
|
198
|
+
constructor(core: WuCore);
|
|
199
|
+
prefetch(appNames: string | string[], options?: any): Promise<void>;
|
|
200
|
+
prefetchAll(options?: any): Promise<void>;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export class WuOverrides {
|
|
204
|
+
constructor();
|
|
205
|
+
set(name: string, url: string, options?: any): void;
|
|
206
|
+
remove(name: string): void;
|
|
207
|
+
getAll(): Record<string, string>;
|
|
208
|
+
clearAll(): void;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export class WuErrorBoundary {
|
|
212
|
+
constructor(core: WuCore);
|
|
213
|
+
handle(error: Error, context?: any): Promise<{ recovered: boolean; action: string; message?: string }>;
|
|
214
|
+
register(handler: { name: string; canHandle: (error: Error) => boolean; handle: (error: Error, context: any) => Promise<any> }): void;
|
|
215
|
+
getErrorLog(limit?: number): any[];
|
|
216
|
+
getStats(): Record<string, any>;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export class WuLifecycleHooks {
|
|
220
|
+
constructor(core: WuCore);
|
|
221
|
+
use(phase: string, middleware: Function, options?: any): void;
|
|
222
|
+
execute(phase: string, context?: any): Promise<{ cancelled: boolean }>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export class WuStyleBridge {}
|
|
226
|
+
|
|
227
|
+
// --- Hook Factories ---
|
|
228
|
+
|
|
229
|
+
export function createSimpleHook(fn: Function): any;
|
|
230
|
+
export function createConditionalHook(condition: Function, fn: Function): any;
|
|
231
|
+
export function createGuardHook(fn: Function): any;
|
|
232
|
+
export function createTransformHook(fn: Function): any;
|
|
233
|
+
export function createTimedHook(fn: Function, timeout: number): any;
|
|
234
|
+
export function createPlugin(config: WuPlugin): WuPlugin;
|
|
235
|
+
|
|
236
|
+
// --- Convenience API ---
|
|
237
|
+
|
|
238
|
+
export const wu: WuCore;
|
|
239
|
+
export default wu;
|
|
240
|
+
|
|
241
|
+
export function init(apps: WuAppConfig[]): Promise<void>;
|
|
242
|
+
export function mount(name: string, container: string): Promise<void>;
|
|
243
|
+
export function unmount(name: string, opts?: any): Promise<void>;
|
|
244
|
+
export function define(name: string, lifecycle: WuLifecycle): void;
|
|
245
|
+
export function app(name: string, config: Partial<WuAppConfig>): WuApp;
|
|
246
|
+
export function destroy(): void;
|
|
247
|
+
export function hide(name: string): Promise<void>;
|
|
248
|
+
export function show(name: string): Promise<void>;
|
|
249
|
+
export function isHidden(name: string): boolean;
|
|
250
|
+
|
|
251
|
+
export function emit(event: string, data?: any, opts?: any): boolean;
|
|
252
|
+
export function on(event: string, cb: (event: WuEvent) => void): () => void;
|
|
253
|
+
export function once(event: string, cb: (event: WuEvent) => void): () => void;
|
|
254
|
+
export function off(event: string, cb: (event: WuEvent) => void): void;
|
|
255
|
+
|
|
256
|
+
export function getState(path?: string): any;
|
|
257
|
+
export function setState(path: string, value: any): number;
|
|
258
|
+
export function onStateChange(pattern: string, cb: (value: any) => void): () => void;
|
|
259
|
+
|
|
260
|
+
export function startMeasure(name: string, app?: string): void;
|
|
261
|
+
export function endMeasure(name: string, app?: string): number;
|
|
262
|
+
export function generatePerformanceReport(): Record<string, any>;
|
|
263
|
+
|
|
264
|
+
export function prefetch(appNames: string | string[], opts?: any): Promise<void>;
|
|
265
|
+
export function prefetchAll(opts?: any): Promise<void>;
|
|
266
|
+
|
|
267
|
+
export function override(name: string, url: string, opts?: any): void;
|
|
268
|
+
export function removeOverride(name: string): void;
|
|
269
|
+
export function getOverrides(): Record<string, string>;
|
|
270
|
+
export function clearOverrides(): void;
|
|
271
|
+
|
|
272
|
+
export function usePlugin(plugin: WuPlugin | Function, opts?: any): void;
|
|
273
|
+
export function useHook(phase: string, middleware: Function, opts?: any): void;
|
|
274
|
+
|
|
275
|
+
export function silenceAllLogs(): void;
|
|
276
|
+
export function enableAllLogs(): void;
|
|
277
|
+
|
|
278
|
+
// --- AI Classes ---
|
|
279
|
+
|
|
280
|
+
export class WuAI {
|
|
281
|
+
provider(name: string, config: any): void;
|
|
282
|
+
send(message: string, options?: any): Promise<any>;
|
|
283
|
+
stream(message: string, options?: any): AsyncGenerator<any>;
|
|
284
|
+
json(message: string, options?: any): Promise<any>;
|
|
285
|
+
action(name: string, config: any): void;
|
|
286
|
+
agent(goal: string, options?: any): Promise<any>;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export class WuAIProvider {}
|
|
290
|
+
export class WuAIPermissions {}
|
|
291
|
+
export class WuAIContext {}
|
|
292
|
+
export class WuAIActions {}
|
|
293
|
+
export class WuAIConversation {}
|
|
294
|
+
export class WuAITriggers {}
|
|
295
|
+
export class WuAIAgent {}
|
|
296
|
+
export class WuAIOrchestrate {}
|
|
297
|
+
|
|
298
|
+
export function sanitizeForPrompt(text: string): string;
|
|
299
|
+
export function redactSensitive(text: string): string;
|
|
300
|
+
export function interpolate(template: string, vars: Record<string, any>): string;
|
|
301
|
+
export function buildToolSchemas(actions: any): any;
|
|
302
|
+
export function normalizeParameters(params: any): any;
|
|
303
|
+
export function validateParams(params: any, schema: any): boolean;
|
|
304
|
+
export function estimateTokens(text: string): number;
|
|
305
|
+
export function truncateToTokenBudget(text: string, budget: number): string;
|
|
306
|
+
|
|
307
|
+
// --- MCP & Browser ---
|
|
308
|
+
|
|
309
|
+
export function createMcpBridge(core: WuCore): any;
|
|
310
|
+
export function registerBrowserActions(ai: WuAI): void;
|
|
311
|
+
export function ensureInterceptors(): void;
|
|
312
|
+
export function captureScreenshot(): Promise<string>;
|
|
313
|
+
export function buildA11yTree(): any;
|
|
314
|
+
export function clickElement(selector: string): Promise<void>;
|
|
315
|
+
export function typeIntoElement(selector: string, text: string): Promise<void>;
|
|
316
|
+
export function getFilteredNetwork(): any[];
|
|
317
|
+
export function getFilteredConsole(): any[];
|
package/src/index.js
CHANGED
|
@@ -25,14 +25,24 @@ if (typeof window !== 'undefined' && window.wu && window.wu._isWuFramework) {
|
|
|
25
25
|
} else {
|
|
26
26
|
wu = new WuCore();
|
|
27
27
|
wu._isWuFramework = true;
|
|
28
|
+
|
|
29
|
+
// Also store on a Symbol key for collision-safe access
|
|
30
|
+
if (typeof window !== 'undefined') {
|
|
31
|
+
const WU_KEY = Symbol.for('wu-framework');
|
|
32
|
+
window[WU_KEY] = wu;
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
// Expose globally for microfrontends
|
|
31
37
|
if (typeof window !== 'undefined') {
|
|
38
|
+
// Warn if window.wu exists but is not a Wu Framework instance
|
|
39
|
+
if (window.wu && !window.wu._isWuFramework) {
|
|
40
|
+
console.warn('[Wu Framework] window.wu already exists and is not a Wu Framework instance. Overwriting. Use Symbol.for("wu-framework") for collision-safe access.');
|
|
41
|
+
}
|
|
32
42
|
window.wu = wu;
|
|
33
43
|
|
|
34
44
|
if (!wu.version) {
|
|
35
|
-
wu.version = '1.1.
|
|
45
|
+
wu.version = '1.1.17';
|
|
36
46
|
wu.info = {
|
|
37
47
|
name: 'Wu Framework',
|
|
38
48
|
description: 'Universal Microfrontends',
|