@solarpunkltd/swarm-chat-js 4.2.3 → 5.0.1
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 +51 -99
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +2848 -2676
- package/dist/index.js +10 -10
- package/dist/interfaces/message.d.ts +19 -0
- package/dist/interfaces/message.d.ts.map +1 -1
- package/dist/lib/core.d.ts +3 -2
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/history.d.ts +15 -2
- package/dist/lib/history.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +3 -2
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/swarm-chat-umd.js +10 -10
- package/dist/utils/validation.d.ts +15 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ npm/pnpm install @solarpunkltd/swarm-chat-js
|
|
|
43
43
|
### Imports
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import { EVENTS, MessageData, SwarmChat, ChatSettings } from '@solarpunkltd/swarm-chat-js';
|
|
46
|
+
import { EVENTS, MessageData, MessageType, SwarmChat, ChatSettings } from '@solarpunkltd/swarm-chat-js';
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
### `ChatSettings` Interface
|
|
@@ -106,118 +106,69 @@ The `SwarmChat` class instance provides the following core methods:
|
|
|
106
106
|
- `start()`: Initializes and starts the chat service, including setting up listeners and beginning to poll for messages.
|
|
107
107
|
- `stop()`: Stops the chat service, clears intervals, and cleans up resources.
|
|
108
108
|
- `getEmitter()`: Returns an event emitter instance, allowing your application to subscribe to the `EVENTS` listed above.
|
|
109
|
-
- `sendMessage(message: string)`: Initiates the process of sending a new chat message from the current user.
|
|
109
|
+
- `sendMessage(message: string, type: MessageType, targetMessageId?: string, id?: string)`: Initiates the process of sending a new chat message from the current user. Supports different message types including text, threads, and reactions.
|
|
110
110
|
- `fetchPreviousMessages()`: Manually triggers the fetching of older messages from the aggregated chat feed.
|
|
111
|
+
- `hasPreviousMessages()`: Returns a boolean indicating whether there are previous messages available to fetch (determined by checking if more than one message state reference exists).
|
|
111
112
|
- `retrySendMessage(message: MessageData)`: Attempts to resend a message that previously encountered an error during the initial request phase (e.g., failed to write to the user's own feed).
|
|
112
113
|
- `retryBroadcastUserMessage(message: MessageData)`: Attempts to re-broadcast a message update via GSOC if the message was successfully uploaded to the user's feed but the GSOC broadcast might have failed or needs retrying.
|
|
113
114
|
|
|
115
|
+
### Message Types
|
|
116
|
+
|
|
117
|
+
The library supports three types of messages through the `MessageType` enum:
|
|
118
|
+
|
|
119
|
+
- `MessageType.TEXT`: Regular chat messages
|
|
120
|
+
- `MessageType.THREAD`: Reply messages that reference a parent message via `targetMessageId`
|
|
121
|
+
- `MessageType.REACTION`: Emoji reactions to existing messages, also using `targetMessageId` to reference the target message
|
|
122
|
+
|
|
123
|
+
### Message State Management
|
|
124
|
+
|
|
125
|
+
The library includes robust message state handling with:
|
|
126
|
+
|
|
127
|
+
- **Automatic retry logic**: Failed message state references are automatically retried with exponential backoff
|
|
128
|
+
- **Ref banning**: Persistently failing references are banned after maximum retry attempts to prevent infinite loops
|
|
129
|
+
- **Efficient caching**: Message state data is cached to avoid redundant network requests
|
|
130
|
+
|
|
114
131
|
---
|
|
115
132
|
|
|
116
133
|
## 🚀 Usage Example (React)
|
|
117
134
|
|
|
118
135
|
Here's an example of how `swarm-chat-js` can be integrated into a React application using a custom hook (`useSwarmChat`). This hook encapsulates chat logic, state management, and event handling.
|
|
119
136
|
|
|
137
|
+
### Complete Implementation
|
|
138
|
+
|
|
139
|
+
For a full working example, check out our React integration:
|
|
140
|
+
|
|
141
|
+
**📖 [View Complete useSwarmChat Hook Implementation](https://github.com/Solar-Punk-Ltd/swarm-chat-react-example/blob/master/src/hooks/useSwarmChat.tsx)**
|
|
142
|
+
|
|
143
|
+
### Basic Usage
|
|
144
|
+
|
|
120
145
|
```typescript
|
|
121
|
-
import {
|
|
122
|
-
import {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
uploaded?: boolean;
|
|
127
|
-
received?: boolean;
|
|
128
|
-
error?: boolean;
|
|
129
|
-
}
|
|
146
|
+
import { useSwarmChat } from './hooks/useSwarmChat';
|
|
147
|
+
import { MessageType } from '@solarpunkltd/swarm-chat-js';
|
|
148
|
+
|
|
149
|
+
function ChatComponent() {
|
|
150
|
+
const { messages, isLoading, sendMessage, hasPreviousMessages, loadPreviousMessages } = useSwarmChat(chatSettings);
|
|
130
151
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const messageCache = useRef<VisibleMessage[]>([]);
|
|
134
|
-
const [allMessages, setAllMessages] = useState<VisibleMessage[]>([]);
|
|
135
|
-
const [chatLoading, setChatLoading] = useState<boolean>(true);
|
|
136
|
-
const [messagesLoading, setMessagesLoading] = useState<boolean>(false);
|
|
137
|
-
const [error, setError] = useState<any | null>(null);
|
|
138
|
-
|
|
139
|
-
useEffect(() => {
|
|
140
|
-
if (!chat.current) {
|
|
141
|
-
const newChat = new SwarmChat({
|
|
142
|
-
user,
|
|
143
|
-
infra,
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
chat.current = newChat;
|
|
147
|
-
|
|
148
|
-
const { on } = newChat.getEmitter();
|
|
149
|
-
|
|
150
|
-
const updateMessage = (id: string, updates: Partial<VisibleMessage>) => {
|
|
151
|
-
messageCache.current = messageCache.current.map((msg) => (msg.id === id ? { ...msg, ...updates } : msg));
|
|
152
|
-
setAllMessages(chat.current?.orderMessages([...messageCache.current]) || []);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const handleMessageEvent = (event: string, updates: Partial<VisibleMessage>) => {
|
|
156
|
-
on(event, (d: MessageData | string) => {
|
|
157
|
-
const data = typeof d === 'string' ? JSON.parse(d) : d;
|
|
158
|
-
|
|
159
|
-
const existingMessage = messageCache.current.find((msg) => msg.id === data.id);
|
|
160
|
-
if (existingMessage) {
|
|
161
|
-
updateMessage(data.id, updates);
|
|
162
|
-
} else {
|
|
163
|
-
messageCache.current.push({ ...data, ...updates });
|
|
164
|
-
setAllMessages(chat.current?.orderMessages([...messageCache.current]) || []);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
handleMessageEvent(EVENTS.MESSAGE_REQUEST_INITIATED, {
|
|
170
|
-
error: false,
|
|
171
|
-
requested: true,
|
|
172
|
-
});
|
|
173
|
-
handleMessageEvent(EVENTS.MESSAGE_REQUEST_UPLOADED, {
|
|
174
|
-
error: false,
|
|
175
|
-
uploaded: true,
|
|
176
|
-
});
|
|
177
|
-
handleMessageEvent(EVENTS.MESSAGE_RECEIVED, {
|
|
178
|
-
error: false,
|
|
179
|
-
received: true,
|
|
180
|
-
});
|
|
181
|
-
handleMessageEvent(EVENTS.MESSAGE_REQUEST_ERROR, { error: true });
|
|
182
|
-
|
|
183
|
-
on(EVENTS.LOADING_INIT, setChatLoading);
|
|
184
|
-
on(EVENTS.LOADING_PREVIOUS_MESSAGES, setMessagesLoading);
|
|
185
|
-
on(EVENTS.CRITICAL_ERROR, setError);
|
|
186
|
-
|
|
187
|
-
newChat.start();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return () => {
|
|
191
|
-
if (chat.current) {
|
|
192
|
-
chat.current.stop();
|
|
193
|
-
chat.current = null;
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
}, [user.privateKey]);
|
|
197
|
-
|
|
198
|
-
const sendMessage = (message: string) => chat.current?.sendMessage(message);
|
|
199
|
-
|
|
200
|
-
const fetchPreviousMessages = () => chat.current?.fetchPreviousMessages();
|
|
201
|
-
|
|
202
|
-
const retrySendMessage = (message: VisibleMessage) => {
|
|
203
|
-
if (message.requested && message.error) {
|
|
204
|
-
chat.current?.retrySendMessage(message);
|
|
205
|
-
}
|
|
206
|
-
if (message.uploaded && message.error) {
|
|
207
|
-
chat.current?.retryBroadcastUserMessage(message);
|
|
208
|
-
}
|
|
152
|
+
const handleSendMessage = (text: string) => {
|
|
153
|
+
sendMessage(text, MessageType.TEXT);
|
|
209
154
|
};
|
|
210
155
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
messagesLoading,
|
|
214
|
-
allMessages,
|
|
215
|
-
sendMessage,
|
|
216
|
-
fetchPreviousMessages,
|
|
217
|
-
retrySendMessage,
|
|
218
|
-
error,
|
|
156
|
+
const handleReaction = (targetMessageId: string, emoji: string) => {
|
|
157
|
+
sendMessage(emoji, MessageType.REACTION, targetMessageId);
|
|
219
158
|
};
|
|
220
|
-
|
|
159
|
+
|
|
160
|
+
const handleReply = (targetMessageId: string, replyText: string) => {
|
|
161
|
+
sendMessage(replyText, MessageType.THREAD, targetMessageId);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<div className="chat-container">
|
|
166
|
+
{/* Your chat UI implementation */}
|
|
167
|
+
{hasPreviousMessages() && <button onClick={loadPreviousMessages}>Load Previous Messages</button>}
|
|
168
|
+
{/* Message list, input field, etc. */}
|
|
169
|
+
</div>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
221
172
|
```
|
|
222
173
|
|
|
223
174
|
---
|
|
@@ -244,7 +195,8 @@ npm run mine -- <bee-address> <topic-name>
|
|
|
244
195
|
|
|
245
196
|
## 💡 Future Development
|
|
246
197
|
|
|
247
|
-
- **Push-Based Event System:** We are actively designing a new architecture to transition from the polling mechanism to a more efficient, push-based event system for message delivery. This will significantly reduce node load and improve real-time message propagation.
|
|
198
|
+
- **Push-Based Event System:** We are actively designing a new architecture to transition from the polling mechanism to a more efficient, push-based event system for message delivery. This will significantly reduce node load and improve real-time message propagation.
|
|
199
|
+
- **Performance Optimizations:** Further improvements to message state handling and caching mechanisms.
|
|
248
200
|
|
|
249
201
|
---
|
|
250
202
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { SwarmChat } from './lib/core';
|
|
2
2
|
export { EVENTS } from './lib/constants';
|
|
3
|
-
export type { MessageData, ChatSettings } from './interfaces';
|
|
3
|
+
export type { MessageData, ChatSettings, StatefulMessage, MessageStateRef } from './interfaces';
|
|
4
|
+
export { MessageType } from './interfaces';
|
|
4
5
|
export type { EthAddress } from '../node_modules/@ethersphere/bee-js/dist/types/index.d.ts';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhG,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|