@melony/react 0.1.11 → 0.1.14

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 CHANGED
@@ -1,237 +1,98 @@
1
1
  # @melony/react
2
2
 
3
- React components and hooks for building AI chat interfaces with Melony.
3
+ React UI + providers/hooks for building chat experiences on top of **Melony’s event stream**, including automatic rendering for **Server‑Driven UI (SDUI)** (`event.ui`).
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @melony/react
8
+ npm install @melony/react melony react
9
9
  ```
10
10
 
11
- ## Quick Start
11
+ ## Quick start
12
12
 
13
13
  ```tsx
14
- import { MelonyStoreProvider, Thread, ThreadSidebar, useMelony } from "@melony/react";
14
+ import React from "react";
15
+ import { MelonyClient, createHttpTransport } from "melony/client";
16
+ import { MelonyClientProvider, Thread } from "@melony/react";
15
17
 
16
- function ThreadApp() {
17
- const { threads, activeThreadId, messages, isLoading } = useMelony();
18
-
19
- return (
20
- <div style={{ display: 'flex', height: '100vh' }}>
21
- <ThreadSidebar threads={threads} activeThreadId={activeThreadId} />
22
- <Thread messages={messages} isLoading={isLoading} />
23
- </div>
24
- );
25
- }
18
+ const client = new MelonyClient(createHttpTransport("/api/chat"));
26
19
 
27
20
  export default function App() {
28
21
  return (
29
- <MelonyStoreProvider api="/api/chat">
30
- <ThreadApp />
31
- </MelonyStoreProvider>
22
+ <MelonyClientProvider client={client}>
23
+ <Thread />
24
+ </MelonyClientProvider>
32
25
  );
33
26
  }
34
27
  ```
35
28
 
36
- ## Architecture
37
-
38
- Melony React uses an **event-based architecture** where all actions are dispatched as events:
39
-
40
- ```tsx
41
- const { dispatchEvent } = useMelony();
42
-
43
- // Create a thread
44
- dispatchEvent({ type: 'createThread' });
45
-
46
- // Switch thread
47
- dispatchEvent({ type: 'switchThread', data: { threadId: 'abc' } });
48
-
49
- // Send a message
50
- dispatchEvent({
51
- type: 'sendMessage',
52
- data: {
53
- role: 'user',
54
- content: [{ type: 'text', data: { content: 'Hello!' } }]
55
- }
56
- });
57
- ```
58
-
59
- ## Core Components
60
-
61
- ### `MelonyStoreProvider`
62
-
63
- The main provider that manages threads, messages, and API communication.
64
-
65
- ```tsx
66
- <MelonyStoreProvider
67
- api="/api/chat"
68
- onLoadHistory={async (threadId) => {
69
- // Load message history when switching threads
70
- const res = await fetch(`/api/threads/${threadId}/messages`);
71
- return res.json();
72
- }}
73
- onThreadsChange={(threads) => {
74
- // Persist threads (e.g., to localStorage)
75
- localStorage.setItem('threads', JSON.stringify(threads));
76
- }}
77
- onEvent={(event) => {
78
- // Handle custom events
79
- console.log('Event:', event.type);
80
- }}
81
- >
82
- <App />
83
- </MelonyStoreProvider>
84
- ```
85
-
86
- ### `Thread`
29
+ ### Send a message from UI
87
30
 
88
- The main thread interface component.
31
+ `Thread` already wires this up, but if you want manual control:
89
32
 
90
33
  ```tsx
91
- <Thread
92
- messages={messages}
93
- isLoading={isLoading}
94
- placeholder="Type a message..."
95
- components={{
96
- // Custom components for Server-Driven UI
97
- 'weather-card': WeatherCard,
98
- }}
99
- />
100
- ```
101
-
102
- ### `ThreadSidebar`
103
-
104
- Sidebar showing list of conversation threads.
34
+ import { useMelony } from "@melony/react";
105
35
 
106
- ```tsx
107
- <ThreadSidebar
108
- threads={threads}
109
- activeThreadId={activeThreadId}
110
- width={280}
111
- />
36
+ function Controls() {
37
+ const { sendEvent, isLoading } = useMelony();
38
+ return (
39
+ <button
40
+ disabled={isLoading}
41
+ onClick={() =>
42
+ sendEvent({ type: "text", role: "user", data: { content: "Hello!" } })
43
+ }
44
+ >
45
+ Send
46
+ </button>
47
+ );
48
+ }
112
49
  ```
113
50
 
114
- ## Hooks
115
-
116
- ### `useMelony()`
117
-
118
- Main hook to access store state and dispatch events.
119
-
120
- ```tsx
121
- const {
122
- // State
123
- threads, // Thread[] - all threads
124
- activeThreadId, // string | null
125
- activeThread, // Thread | undefined
126
- messages, // ChatMessage[] - messages in active thread
127
- isLoading, // boolean
128
- error, // Error | null
129
-
130
- // Methods
131
- dispatchEvent, // (event: Event) => void
132
- getThread, // (id: string) => Thread | undefined
133
- getThreadMessages, // (id: string) => ChatMessage[]
134
- } = useMelony();
135
- ```
51
+ ## Components
136
52
 
137
- ### `useDispatchedEvent()`
53
+ - **`Thread`**: a full chat thread (composer + message list + streaming).
54
+ - **`ChatSidebar`**: a sidebar-style chat UI container.
55
+ - **`ChatFull` / `ChatPopup`**: ready-to-embed layouts (see exports).
56
+ - **`UIRenderer`**: renders SDUI `UINode` trees from `melony`.
138
57
 
139
- Listen to events dispatched through the system.
58
+ ## Providers & hooks
140
59
 
141
- ```tsx
142
- useDispatchedEvent((event) => {
143
- if (event.type === 'sendMessage') {
144
- console.log('Message sent!');
145
- }
146
- });
147
- ```
60
+ - **`MelonyClientProvider`** + **`useMelony()`**
61
+ - wraps a `MelonyClient` from `melony/client`
62
+ - exposes `events`, `messages`, `isLoading`, `error`, and `sendEvent()`
148
63
 
149
- ## Event Types
64
+ - **`ThreadProvider`** + **`useThreads()`** (optional)
65
+ - adds “thread list / active thread” state
66
+ - you bring a `ThreadService` (load threads, load events, delete thread, etc.)
150
67
 
151
- | Event | Data | Description |
152
- |-------|------|-------------|
153
- | `createThread` | `{ initialMessage?, title? }` | Create a new thread |
154
- | `switchThread` | `{ threadId }` | Switch to a thread |
155
- | `deleteThread` | `{ threadId }` | Delete a thread |
156
- | `updateThreadTitle` | `{ threadId, title }` | Update thread title |
157
- | `sendMessage` | `{ role, content, threadId? }` | Send a message |
158
- | `clearThread` | `{ threadId? }` | Clear thread messages |
68
+ - **`AuthProvider`** + **`useAuth()`** (optional)
69
+ - plug in an `AuthService` (login/logout/me/token) for authenticated apps
159
70
 
160
- ## UI Components
71
+ ## SDUI (Server‑Driven UI)
161
72
 
162
- Layout: `Row`, `Col`, `Box`, `Spacer`, `Divider`, `List`, `ListItem`
163
- Content: `Text`, `Heading`, `Image`, `Icon`, `Badge`, `Chart`
164
- Forms: `Button`, `Input`, `Textarea`, `Select`, `Checkbox`, `RadioGroup`, `Form`, `Label`
165
- Containers: `Card`
73
+ If the backend yields events with `event.ui`, Melony React renders them automatically inside assistant messages.
166
74
 
167
- ## Server-Driven UI
75
+ Backend example:
168
76
 
169
- Components can render UI from server events:
77
+ ```ts
78
+ import { ui } from "melony";
170
79
 
171
- ```tsx
172
- // Server sends:
173
80
  yield {
174
- type: 'ui',
175
- ui: {
176
- type: 'card',
177
- props: { title: 'Weather' },
178
- children: [
179
- { type: 'text', props: { value: '72°F' } }
180
- ]
181
- }
81
+ type: "ui",
82
+ ui: ui.card({
83
+ title: "Weather",
84
+ children: [ui.text("72°F and sunny")],
85
+ }),
182
86
  };
183
-
184
- // Renderer automatically displays the Card with Text
185
- ```
186
-
187
- ## Theming
188
-
189
- ```tsx
190
- <MelonyStoreProvider
191
- api="/api/chat"
192
- theme={{
193
- colors: {
194
- primary: '#6366f1',
195
- background: '#ffffff',
196
- },
197
- radius: {
198
- md: '8px',
199
- },
200
- }}
201
- >
202
- <App />
203
- </MelonyStoreProvider>
204
87
  ```
205
88
 
206
- ## Migration from Legacy Hooks
207
-
208
- If you're using the deprecated hooks (`useMelonyRuntime`, `useMelonyThread`, `useMelonyThreads`):
209
-
210
- ```tsx
211
- // Before:
212
- const { messages, sendMessage } = useMelonyThread({ api: '/api/chat' });
213
- const { threads, createThread } = useMelonyThreads({ threads, activeThreadId });
214
-
215
- // After:
216
- // 1. Wrap with MelonyStoreProvider
217
- // 2. Use useMelony()
218
- const { messages, threads, dispatchEvent } = useMelony();
219
-
220
- // Send message via event
221
- dispatchEvent({
222
- type: 'sendMessage',
223
- data: { role: 'user', content: [...] }
224
- });
225
-
226
- // Create thread via event
227
- dispatchEvent({ type: 'createThread' });
228
- ```
89
+ Frontend: no extra work — it shows up in the message stream.
229
90
 
230
91
  ## Development
231
92
 
232
93
  ```bash
233
- pnpm build # Build
234
- pnpm dev # Watch mode
235
- pnpm typecheck # Type check
236
- pnpm clean # Clean dist
94
+ pnpm build
95
+ pnpm dev
96
+ pnpm typecheck
97
+ pnpm clean
237
98
  ```