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.
Files changed (51) hide show
  1. package/README.md +52 -20
  2. package/package.json +48 -3
  3. package/src/adapters/alpine/index.d.ts +60 -0
  4. package/src/adapters/alpine/index.js +231 -0
  5. package/src/adapters/alpine.d.ts +3 -0
  6. package/src/adapters/alpine.js +3 -0
  7. package/src/adapters/htmx/index.d.ts +60 -0
  8. package/src/adapters/htmx/index.js +242 -0
  9. package/src/adapters/htmx.d.ts +3 -0
  10. package/src/adapters/htmx.js +3 -0
  11. package/src/adapters/index.js +60 -3
  12. package/src/adapters/qwik/index.d.ts +52 -0
  13. package/src/adapters/qwik/index.js +214 -0
  14. package/src/adapters/qwik.d.ts +3 -0
  15. package/src/adapters/qwik.js +3 -0
  16. package/src/adapters/react/ai.js +135 -135
  17. package/src/adapters/react/index.d.ts +246 -246
  18. package/src/adapters/react/index.js +695 -695
  19. package/src/adapters/stencil/index.d.ts +54 -0
  20. package/src/adapters/stencil/index.js +228 -0
  21. package/src/adapters/stencil.d.ts +3 -0
  22. package/src/adapters/stencil.js +3 -0
  23. package/src/adapters/stimulus/index.d.ts +60 -0
  24. package/src/adapters/stimulus/index.js +255 -0
  25. package/src/adapters/stimulus.d.ts +3 -0
  26. package/src/adapters/stimulus.js +3 -0
  27. package/src/adapters/svelte/index.js +1 -1
  28. package/src/adapters/vanilla/index.js +1 -1
  29. package/src/adapters/vue/index.js +8 -0
  30. package/src/core/wu-cache.js +24 -3
  31. package/src/core/wu-core.js +15 -1
  32. package/src/core/wu-error-boundary.js +17 -3
  33. package/src/core/wu-event-bus.js +43 -1
  34. package/src/core/wu-html-parser.js +13 -4
  35. package/src/core/wu-loader.js +162 -50
  36. package/src/core/wu-logger.js +21 -13
  37. package/src/core/wu-manifest.js +23 -0
  38. package/src/core/wu-plugin.js +57 -4
  39. package/src/core/wu-proxy-sandbox.js +2 -1
  40. package/src/core/wu-script-executor.js +48 -0
  41. package/src/core/wu-store.js +13 -3
  42. package/src/index.d.ts +317 -0
  43. package/src/index.js +11 -1
  44. package/dist/wu-framework.cjs.js +0 -3
  45. package/dist/wu-framework.cjs.js.map +0 -1
  46. package/dist/wu-framework.dev.js +0 -15302
  47. package/dist/wu-framework.dev.js.map +0 -1
  48. package/dist/wu-framework.esm.js +0 -3
  49. package/dist/wu-framework.esm.js.map +0 -1
  50. package/dist/wu-framework.umd.js +0 -3
  51. package/dist/wu-framework.umd.js.map +0 -1
@@ -1,135 +1,135 @@
1
- /**
2
- * WU-AI React Hook
3
- *
4
- * Provides AI integration using React hooks.
5
- * Factory pattern: createUseWuAI(React) returns useWuAI().
6
- *
7
- * @example
8
- * import { createUseWuAI } from 'wu-framework/adapters/react';
9
- * import React from 'react';
10
- *
11
- * const useWuAI = createUseWuAI(React);
12
- * const { messages, send, isStreaming } = useWuAI();
13
- */
14
-
15
- import { getWuInstance } from '../shared.js';
16
-
17
- /**
18
- * Factory that creates the useWuAI hook for React.
19
- *
20
- * @param {object} React - React object with hooks (useState, useCallback, useRef, useEffect)
21
- * @returns {Function} useWuAI(options)
22
- */
23
- export function createUseWuAI(React) {
24
- const { useState, useCallback, useRef, useEffect } = React;
25
-
26
- return function useWuAI(options = {}) {
27
- const { namespace = 'default', onActionExecuted = null } = options;
28
-
29
- const [messages, setMessages] = useState([]);
30
- const [isStreaming, setIsStreaming] = useState(false);
31
- const [error, setError] = useState(null);
32
- const actionListenerRef = useRef(null);
33
-
34
- // Listen for action execution events to provide visual feedback
35
- useEffect(() => {
36
- const wu = getWuInstance();
37
- if (!wu?.eventBus) return;
38
-
39
- const unsub = wu.eventBus.on('ai:action:executed', (event) => {
40
- const actionMsg = {
41
- id: `action-${Date.now()}`,
42
- role: 'action',
43
- content: event.data?.action || 'action',
44
- result: event.data?.result,
45
- timestamp: Date.now(),
46
- };
47
- setMessages((prev) => [...prev, actionMsg]);
48
- if (onActionExecuted) onActionExecuted(event.data);
49
- });
50
-
51
- actionListenerRef.current = unsub;
52
- return () => { if (unsub) unsub(); };
53
- }, [onActionExecuted]);
54
-
55
- const send = useCallback(async (text) => {
56
- if (!text?.trim()) return;
57
- const wu = getWuInstance();
58
- if (!wu?.ai) { setError('Wu AI not available'); return; }
59
-
60
- setMessages((prev) => [...prev, {
61
- id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now(),
62
- }]);
63
- setError(null);
64
- setIsStreaming(true);
65
-
66
- const assistantId = `assistant-${Date.now()}`;
67
- setMessages((prev) => [...prev, {
68
- id: assistantId, role: 'assistant', content: '', timestamp: Date.now(),
69
- }]);
70
-
71
- try {
72
- let fullContent = '';
73
- for await (const chunk of wu.ai.stream(text, { namespace })) {
74
- if (chunk.type === 'text') {
75
- fullContent += chunk.content;
76
- const captured = fullContent;
77
- setMessages((prev) =>
78
- prev.map((m) =>
79
- m.id === assistantId ? { ...m, content: captured } : m,
80
- ),
81
- );
82
- }
83
- if (chunk.type === 'error') {
84
- setError(chunk.error?.message || 'AI request failed');
85
- }
86
- }
87
- } catch (err) {
88
- setError(err.message || 'AI request failed');
89
- setMessages((prev) => prev.filter((m) => m.id !== assistantId || m.content));
90
- } finally {
91
- setIsStreaming(false);
92
- }
93
- }, [namespace]);
94
-
95
- const sendSync = useCallback(async (text) => {
96
- if (!text?.trim()) return null;
97
- const wu = getWuInstance();
98
- if (!wu?.ai) { setError('Wu AI not available'); return null; }
99
-
100
- setMessages((prev) => [...prev, {
101
- id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now(),
102
- }]);
103
- setError(null);
104
- setIsStreaming(true);
105
-
106
- try {
107
- const response = await wu.ai.send(text, { namespace });
108
- setMessages((prev) => [...prev, {
109
- id: `assistant-${Date.now()}`, role: 'assistant', content: response.content, timestamp: Date.now(),
110
- }]);
111
- return response;
112
- } catch (err) {
113
- setError(err.message || 'AI request failed');
114
- return null;
115
- } finally {
116
- setIsStreaming(false);
117
- }
118
- }, [namespace]);
119
-
120
- const abort = useCallback(() => {
121
- const wu = getWuInstance();
122
- if (wu?.ai) wu.ai.abort(namespace);
123
- setIsStreaming(false);
124
- }, [namespace]);
125
-
126
- const clear = useCallback(() => {
127
- setMessages([]);
128
- setError(null);
129
- const wu = getWuInstance();
130
- if (wu?.ai) wu.ai.conversation.clear(namespace);
131
- }, [namespace]);
132
-
133
- return { messages, isStreaming, error, send, sendSync, abort, clear };
134
- };
135
- }
1
+ /**
2
+ * WU-AI React Hook
3
+ *
4
+ * Provides AI integration using React hooks.
5
+ * Factory pattern: createUseWuAI(React) returns useWuAI().
6
+ *
7
+ * @example
8
+ * import { createUseWuAI } from 'wu-framework/adapters/react';
9
+ * import React from 'react';
10
+ *
11
+ * const useWuAI = createUseWuAI(React);
12
+ * const { messages, send, isStreaming } = useWuAI();
13
+ */
14
+
15
+ import { getWuInstance } from '../shared.js';
16
+
17
+ /**
18
+ * Factory that creates the useWuAI hook for React.
19
+ *
20
+ * @param {object} React - React object with hooks (useState, useCallback, useRef, useEffect)
21
+ * @returns {Function} useWuAI(options)
22
+ */
23
+ export function createUseWuAI(React) {
24
+ const { useState, useCallback, useRef, useEffect } = React;
25
+
26
+ return function useWuAI(options = {}) {
27
+ const { namespace = 'default', onActionExecuted = null } = options;
28
+
29
+ const [messages, setMessages] = useState([]);
30
+ const [isStreaming, setIsStreaming] = useState(false);
31
+ const [error, setError] = useState(null);
32
+ const actionListenerRef = useRef(null);
33
+
34
+ // Listen for action execution events to provide visual feedback
35
+ useEffect(() => {
36
+ const wu = getWuInstance();
37
+ if (!wu?.eventBus) return;
38
+
39
+ const unsub = wu.eventBus.on('ai:action:executed', (event) => {
40
+ const actionMsg = {
41
+ id: `action-${Date.now()}`,
42
+ role: 'action',
43
+ content: event.data?.action || 'action',
44
+ result: event.data?.result,
45
+ timestamp: Date.now(),
46
+ };
47
+ setMessages((prev) => [...prev, actionMsg]);
48
+ if (onActionExecuted) onActionExecuted(event.data);
49
+ });
50
+
51
+ actionListenerRef.current = unsub;
52
+ return () => { if (unsub) unsub(); };
53
+ }, [onActionExecuted]);
54
+
55
+ const send = useCallback(async (text) => {
56
+ if (!text?.trim()) return;
57
+ const wu = getWuInstance();
58
+ if (!wu?.ai) { setError('Wu AI not available'); return; }
59
+
60
+ setMessages((prev) => [...prev, {
61
+ id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now(),
62
+ }]);
63
+ setError(null);
64
+ setIsStreaming(true);
65
+
66
+ const assistantId = `assistant-${Date.now()}`;
67
+ setMessages((prev) => [...prev, {
68
+ id: assistantId, role: 'assistant', content: '', timestamp: Date.now(),
69
+ }]);
70
+
71
+ try {
72
+ let fullContent = '';
73
+ for await (const chunk of wu.ai.stream(text, { namespace })) {
74
+ if (chunk.type === 'text') {
75
+ fullContent += chunk.content;
76
+ const captured = fullContent;
77
+ setMessages((prev) =>
78
+ prev.map((m) =>
79
+ m.id === assistantId ? { ...m, content: captured } : m,
80
+ ),
81
+ );
82
+ }
83
+ if (chunk.type === 'error') {
84
+ setError(chunk.error?.message || 'AI request failed');
85
+ }
86
+ }
87
+ } catch (err) {
88
+ setError(err.message || 'AI request failed');
89
+ setMessages((prev) => prev.filter((m) => m.id !== assistantId || m.content));
90
+ } finally {
91
+ setIsStreaming(false);
92
+ }
93
+ }, [namespace]);
94
+
95
+ const sendSync = useCallback(async (text) => {
96
+ if (!text?.trim()) return null;
97
+ const wu = getWuInstance();
98
+ if (!wu?.ai) { setError('Wu AI not available'); return null; }
99
+
100
+ setMessages((prev) => [...prev, {
101
+ id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now(),
102
+ }]);
103
+ setError(null);
104
+ setIsStreaming(true);
105
+
106
+ try {
107
+ const response = await wu.ai.send(text, { namespace });
108
+ setMessages((prev) => [...prev, {
109
+ id: `assistant-${Date.now()}`, role: 'assistant', content: response.content, timestamp: Date.now(),
110
+ }]);
111
+ return response;
112
+ } catch (err) {
113
+ setError(err.message || 'AI request failed');
114
+ return null;
115
+ } finally {
116
+ setIsStreaming(false);
117
+ }
118
+ }, [namespace]);
119
+
120
+ const abort = useCallback(() => {
121
+ const wu = getWuInstance();
122
+ if (wu?.ai) wu.ai.abort(namespace);
123
+ setIsStreaming(false);
124
+ }, [namespace]);
125
+
126
+ const clear = useCallback(() => {
127
+ setMessages([]);
128
+ setError(null);
129
+ const wu = getWuInstance();
130
+ if (wu?.ai) wu.ai.conversation.clear(namespace);
131
+ }, [namespace]);
132
+
133
+ return { messages, isStreaming, error, send, sendSync, abort, clear };
134
+ };
135
+ }