@scalemule/chat 0.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/dist/ChatClient-CXPywp1w.d.cts +59 -0
- package/dist/ChatClient-DCid_mmU.d.ts +59 -0
- package/dist/chat.embed.global.js +1 -0
- package/dist/chat.umd.global.js +18 -0
- package/dist/chunk-6QRI4CJZ.js +739 -0
- package/dist/chunk-NFOVLPF2.cjs +741 -0
- package/dist/element.cjs +108 -0
- package/dist/element.d.cts +2 -0
- package/dist/element.d.ts +2 -0
- package/dist/element.js +106 -0
- package/dist/iframe.cjs +46 -0
- package/dist/iframe.d.cts +17 -0
- package/dist/iframe.d.ts +17 -0
- package/dist/iframe.js +44 -0
- package/dist/index.cjs +12 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/react.cjs +242 -0
- package/dist/react.d.cts +37 -0
- package/dist/react.d.ts +37 -0
- package/dist/react.js +233 -0
- package/dist/types-BwgD_Etd.d.cts +178 -0
- package/dist/types-BwgD_Etd.d.ts +178 -0
- package/package.json +68 -0
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { c as ChatConfig, e as ChatMessage, S as SendMessageOptions, a as ApiResponse, g as ConnectionStatus } from './types-BwgD_Etd.js';
|
|
3
|
+
export { h as Conversation, G as GetMessagesOptions, M as MessagesResponse } from './types-BwgD_Etd.js';
|
|
4
|
+
export { C as ChatClient } from './ChatClient-DCid_mmU.js';
|
|
5
|
+
|
|
6
|
+
interface ChatProviderProps {
|
|
7
|
+
config: ChatConfig;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
declare function ChatProvider({ config, children }: ChatProviderProps): React.JSX.Element;
|
|
11
|
+
declare function useConnection(): {
|
|
12
|
+
status: ConnectionStatus;
|
|
13
|
+
connect: () => void;
|
|
14
|
+
disconnect: () => void;
|
|
15
|
+
};
|
|
16
|
+
declare function useChat(conversationId?: string): {
|
|
17
|
+
messages: ChatMessage[];
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
error: string | null;
|
|
20
|
+
hasMore: boolean;
|
|
21
|
+
sendMessage: (content: string, options?: Partial<SendMessageOptions>) => Promise<ApiResponse<ChatMessage> | undefined>;
|
|
22
|
+
loadMore: () => Promise<void>;
|
|
23
|
+
markRead: () => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
declare function usePresence(conversationId?: string): {
|
|
26
|
+
members: {
|
|
27
|
+
userId: string;
|
|
28
|
+
status: string;
|
|
29
|
+
userData?: unknown;
|
|
30
|
+
}[];
|
|
31
|
+
};
|
|
32
|
+
declare function useTyping(conversationId?: string): {
|
|
33
|
+
typingUsers: string[];
|
|
34
|
+
sendTyping: (isTyping?: boolean) => void;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { ApiResponse, ChatConfig, ChatMessage, ChatProvider, ConnectionStatus, SendMessageOptions, useChat, useConnection, usePresence, useTyping };
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { ChatClient } from './chunk-6QRI4CJZ.js';
|
|
2
|
+
export { ChatClient } from './chunk-6QRI4CJZ.js';
|
|
3
|
+
import { createContext, useState, useEffect, useCallback, useRef, useContext } from 'react';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var ChatContext = createContext(null);
|
|
7
|
+
function useChatContext() {
|
|
8
|
+
const ctx = useContext(ChatContext);
|
|
9
|
+
if (!ctx) throw new Error("useChatContext must be used within a ChatProvider");
|
|
10
|
+
return ctx;
|
|
11
|
+
}
|
|
12
|
+
function ChatProvider({ config, children }) {
|
|
13
|
+
const [client] = useState(() => new ChatClient(config));
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
return () => {
|
|
16
|
+
client.destroy();
|
|
17
|
+
};
|
|
18
|
+
}, [client]);
|
|
19
|
+
return /* @__PURE__ */ jsx(ChatContext.Provider, { value: { client }, children });
|
|
20
|
+
}
|
|
21
|
+
function useConnection() {
|
|
22
|
+
const { client } = useChatContext();
|
|
23
|
+
const [status, setStatus] = useState(client.status);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
return client.on("connected", () => setStatus("connected"));
|
|
26
|
+
}, [client]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
return client.on("disconnected", () => setStatus("disconnected"));
|
|
29
|
+
}, [client]);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
return client.on("reconnecting", () => setStatus("reconnecting"));
|
|
32
|
+
}, [client]);
|
|
33
|
+
return {
|
|
34
|
+
status,
|
|
35
|
+
connect: () => client.connect(),
|
|
36
|
+
disconnect: () => client.disconnect()
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function useChat(conversationId) {
|
|
40
|
+
const { client } = useChatContext();
|
|
41
|
+
const [messages, setMessages] = useState([]);
|
|
42
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
43
|
+
const [error, setError] = useState(null);
|
|
44
|
+
const [hasMore, setHasMore] = useState(false);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!conversationId) return;
|
|
47
|
+
setIsLoading(true);
|
|
48
|
+
setError(null);
|
|
49
|
+
let cancelled = false;
|
|
50
|
+
let unsub;
|
|
51
|
+
(async () => {
|
|
52
|
+
await client.getConversation(conversationId);
|
|
53
|
+
if (cancelled) return;
|
|
54
|
+
const result = await client.getMessages(conversationId);
|
|
55
|
+
if (cancelled) return;
|
|
56
|
+
if (result.data?.messages) {
|
|
57
|
+
setMessages(result.data.messages);
|
|
58
|
+
setHasMore(result.data.has_more ?? false);
|
|
59
|
+
} else if (result.error) {
|
|
60
|
+
setError(result.error.message);
|
|
61
|
+
}
|
|
62
|
+
setIsLoading(false);
|
|
63
|
+
unsub = client.subscribeToConversation(conversationId);
|
|
64
|
+
client.connect();
|
|
65
|
+
})();
|
|
66
|
+
return () => {
|
|
67
|
+
cancelled = true;
|
|
68
|
+
unsub?.();
|
|
69
|
+
};
|
|
70
|
+
}, [client, conversationId]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!conversationId) return;
|
|
73
|
+
return client.on("message", ({ message, conversationId: convId }) => {
|
|
74
|
+
if (convId === conversationId) {
|
|
75
|
+
setMessages((prev) => {
|
|
76
|
+
if (prev.some((m) => m.id === message.id)) return prev;
|
|
77
|
+
return [...prev, message];
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}, [client, conversationId]);
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (!conversationId) return;
|
|
84
|
+
return client.on("message:updated", ({ message, conversationId: convId }) => {
|
|
85
|
+
if (convId === conversationId) {
|
|
86
|
+
setMessages((prev) => prev.map((m) => m.id === message.id ? message : m));
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}, [client, conversationId]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (!conversationId) return;
|
|
92
|
+
return client.on("message:deleted", ({ messageId, conversationId: convId }) => {
|
|
93
|
+
if (convId === conversationId) {
|
|
94
|
+
setMessages((prev) => prev.filter((m) => m.id !== messageId));
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}, [client, conversationId]);
|
|
98
|
+
const sendMessage = useCallback(
|
|
99
|
+
async (content, options) => {
|
|
100
|
+
if (!conversationId) return;
|
|
101
|
+
return client.sendMessage(conversationId, { content, ...options });
|
|
102
|
+
},
|
|
103
|
+
[client, conversationId]
|
|
104
|
+
);
|
|
105
|
+
const loadMore = useCallback(async () => {
|
|
106
|
+
if (!conversationId || !messages.length) return;
|
|
107
|
+
const oldestId = messages[0]?.id;
|
|
108
|
+
const result = await client.getMessages(conversationId, { before: oldestId });
|
|
109
|
+
if (result.data?.messages) {
|
|
110
|
+
setMessages((prev) => [...result.data.messages, ...prev]);
|
|
111
|
+
setHasMore(result.data.has_more ?? false);
|
|
112
|
+
}
|
|
113
|
+
}, [client, conversationId, messages]);
|
|
114
|
+
const markRead = useCallback(async () => {
|
|
115
|
+
if (!conversationId) return;
|
|
116
|
+
await client.markRead(conversationId);
|
|
117
|
+
}, [client, conversationId]);
|
|
118
|
+
return {
|
|
119
|
+
messages,
|
|
120
|
+
isLoading,
|
|
121
|
+
error,
|
|
122
|
+
hasMore,
|
|
123
|
+
sendMessage,
|
|
124
|
+
loadMore,
|
|
125
|
+
markRead
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function usePresence(conversationId) {
|
|
129
|
+
const { client } = useChatContext();
|
|
130
|
+
const [members, setMembers] = useState([]);
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (!conversationId) return;
|
|
133
|
+
let cancelled = false;
|
|
134
|
+
(async () => {
|
|
135
|
+
await client.getConversation(conversationId);
|
|
136
|
+
if (cancelled) return;
|
|
137
|
+
client.joinPresence(conversationId);
|
|
138
|
+
})();
|
|
139
|
+
const unsubState = client.on("presence:state", ({ conversationId: convId, members: m }) => {
|
|
140
|
+
if (convId === conversationId) {
|
|
141
|
+
setMembers(
|
|
142
|
+
m.map((p) => ({
|
|
143
|
+
userId: p.user_id,
|
|
144
|
+
status: p.status ?? "online",
|
|
145
|
+
userData: p.user_data
|
|
146
|
+
}))
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
const unsubJoin = client.on("presence:join", ({ conversationId: convId, userId, userData }) => {
|
|
151
|
+
if (convId === conversationId) {
|
|
152
|
+
setMembers((prev) => {
|
|
153
|
+
if (prev.some((m) => m.userId === userId)) return prev;
|
|
154
|
+
return [...prev, { userId, status: "online", userData }];
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
const unsubLeave = client.on("presence:leave", ({ conversationId: convId, userId }) => {
|
|
159
|
+
if (convId === conversationId) {
|
|
160
|
+
setMembers((prev) => prev.filter((m) => m.userId !== userId));
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const unsubUpdate = client.on(
|
|
164
|
+
"presence:update",
|
|
165
|
+
({ conversationId: convId, userId, status, userData }) => {
|
|
166
|
+
if (convId === conversationId) {
|
|
167
|
+
setMembers(
|
|
168
|
+
(prev) => prev.map(
|
|
169
|
+
(m) => m.userId === userId ? { ...m, status, userData: userData ?? m.userData } : m
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
return () => {
|
|
176
|
+
cancelled = true;
|
|
177
|
+
client.leavePresence(conversationId);
|
|
178
|
+
unsubState();
|
|
179
|
+
unsubJoin();
|
|
180
|
+
unsubLeave();
|
|
181
|
+
unsubUpdate();
|
|
182
|
+
};
|
|
183
|
+
}, [client, conversationId]);
|
|
184
|
+
return { members };
|
|
185
|
+
}
|
|
186
|
+
function useTyping(conversationId) {
|
|
187
|
+
const { client } = useChatContext();
|
|
188
|
+
const [typingUsers, setTypingUsers] = useState([]);
|
|
189
|
+
const typingTimers = useRef(/* @__PURE__ */ new Map());
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
if (!conversationId) return;
|
|
192
|
+
const unsubTyping = client.on("typing", ({ conversationId: convId, userId }) => {
|
|
193
|
+
if (convId !== conversationId) return;
|
|
194
|
+
setTypingUsers((prev) => prev.includes(userId) ? prev : [...prev, userId]);
|
|
195
|
+
const existing = typingTimers.current.get(userId);
|
|
196
|
+
if (existing) clearTimeout(existing);
|
|
197
|
+
typingTimers.current.set(
|
|
198
|
+
userId,
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
setTypingUsers((prev) => prev.filter((id) => id !== userId));
|
|
201
|
+
typingTimers.current.delete(userId);
|
|
202
|
+
}, 3e3)
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
const unsubStop = client.on("typing:stop", ({ conversationId: convId, userId }) => {
|
|
206
|
+
if (convId !== conversationId) return;
|
|
207
|
+
setTypingUsers((prev) => prev.filter((id) => id !== userId));
|
|
208
|
+
const timer = typingTimers.current.get(userId);
|
|
209
|
+
if (timer) {
|
|
210
|
+
clearTimeout(timer);
|
|
211
|
+
typingTimers.current.delete(userId);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
return () => {
|
|
215
|
+
unsubTyping();
|
|
216
|
+
unsubStop();
|
|
217
|
+
for (const timer of typingTimers.current.values()) {
|
|
218
|
+
clearTimeout(timer);
|
|
219
|
+
}
|
|
220
|
+
typingTimers.current.clear();
|
|
221
|
+
};
|
|
222
|
+
}, [client, conversationId]);
|
|
223
|
+
const sendTyping = useCallback(
|
|
224
|
+
(isTyping = true) => {
|
|
225
|
+
if (!conversationId) return;
|
|
226
|
+
client.sendTyping(conversationId, isTyping);
|
|
227
|
+
},
|
|
228
|
+
[client, conversationId]
|
|
229
|
+
);
|
|
230
|
+
return { typingUsers, sendTyping };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export { ChatProvider, useChat, useConnection, usePresence, useTyping };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
interface ChatConfig {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
embedToken?: string;
|
|
4
|
+
apiBaseUrl?: string;
|
|
5
|
+
applicationId?: string;
|
|
6
|
+
userId?: string;
|
|
7
|
+
sessionToken?: string;
|
|
8
|
+
getToken?: () => Promise<string | null>;
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
reconnect?: {
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
baseDelay?: number;
|
|
13
|
+
maxDelay?: number;
|
|
14
|
+
};
|
|
15
|
+
messageCache?: {
|
|
16
|
+
maxMessages?: number;
|
|
17
|
+
maxConversations?: number;
|
|
18
|
+
};
|
|
19
|
+
offlineQueue?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ApiResponse<T> {
|
|
22
|
+
data: T | null;
|
|
23
|
+
error: ApiError | null;
|
|
24
|
+
}
|
|
25
|
+
interface ApiError {
|
|
26
|
+
code: string;
|
|
27
|
+
message: string;
|
|
28
|
+
status: number;
|
|
29
|
+
details?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
interface Conversation {
|
|
32
|
+
id: string;
|
|
33
|
+
conversation_type: 'direct' | 'group' | 'broadcast' | 'ephemeral' | 'large_room';
|
|
34
|
+
name?: string;
|
|
35
|
+
created_by?: string;
|
|
36
|
+
participant_count?: number;
|
|
37
|
+
last_message_at?: string;
|
|
38
|
+
unread_count?: number;
|
|
39
|
+
created_at: string;
|
|
40
|
+
participants?: Participant[];
|
|
41
|
+
}
|
|
42
|
+
interface Participant {
|
|
43
|
+
user_id: string;
|
|
44
|
+
role: string;
|
|
45
|
+
joined_at: string;
|
|
46
|
+
}
|
|
47
|
+
interface ChatMessage {
|
|
48
|
+
id: string;
|
|
49
|
+
content: string;
|
|
50
|
+
message_type: 'text' | 'image' | 'file' | 'system';
|
|
51
|
+
sender_id: string;
|
|
52
|
+
sender_type?: string;
|
|
53
|
+
sender_agent_model?: string;
|
|
54
|
+
attachments?: Attachment[];
|
|
55
|
+
is_edited: boolean;
|
|
56
|
+
created_at: string;
|
|
57
|
+
}
|
|
58
|
+
interface Attachment {
|
|
59
|
+
file_id: string;
|
|
60
|
+
file_name: string;
|
|
61
|
+
file_size: number;
|
|
62
|
+
mime_type: string;
|
|
63
|
+
presigned_url?: string;
|
|
64
|
+
thumbnail_url?: string;
|
|
65
|
+
}
|
|
66
|
+
interface ReadStatus {
|
|
67
|
+
user_id: string;
|
|
68
|
+
last_read_at?: string;
|
|
69
|
+
}
|
|
70
|
+
interface ChatReaction {
|
|
71
|
+
id: string;
|
|
72
|
+
message_id: string;
|
|
73
|
+
user_id: string;
|
|
74
|
+
emoji: string;
|
|
75
|
+
}
|
|
76
|
+
interface PresenceMember {
|
|
77
|
+
user_id: string;
|
|
78
|
+
user_data?: unknown;
|
|
79
|
+
joined_at: string;
|
|
80
|
+
}
|
|
81
|
+
interface ChannelSettings {
|
|
82
|
+
publisher_user_ids?: string[];
|
|
83
|
+
linked_session_id?: string;
|
|
84
|
+
expires_at?: string;
|
|
85
|
+
max_participants?: number;
|
|
86
|
+
slow_mode_seconds?: number;
|
|
87
|
+
}
|
|
88
|
+
interface ChatEventMap {
|
|
89
|
+
connected: void;
|
|
90
|
+
disconnected: void;
|
|
91
|
+
reconnecting: {
|
|
92
|
+
attempt: number;
|
|
93
|
+
};
|
|
94
|
+
'message': {
|
|
95
|
+
message: ChatMessage;
|
|
96
|
+
conversationId: string;
|
|
97
|
+
};
|
|
98
|
+
'message:updated': {
|
|
99
|
+
message: ChatMessage;
|
|
100
|
+
conversationId: string;
|
|
101
|
+
};
|
|
102
|
+
'message:deleted': {
|
|
103
|
+
messageId: string;
|
|
104
|
+
conversationId: string;
|
|
105
|
+
};
|
|
106
|
+
'typing': {
|
|
107
|
+
userId: string;
|
|
108
|
+
conversationId: string;
|
|
109
|
+
};
|
|
110
|
+
'typing:stop': {
|
|
111
|
+
userId: string;
|
|
112
|
+
conversationId: string;
|
|
113
|
+
};
|
|
114
|
+
'presence:join': {
|
|
115
|
+
userId: string;
|
|
116
|
+
conversationId: string;
|
|
117
|
+
userData?: unknown;
|
|
118
|
+
};
|
|
119
|
+
'presence:leave': {
|
|
120
|
+
userId: string;
|
|
121
|
+
conversationId: string;
|
|
122
|
+
};
|
|
123
|
+
'presence:update': {
|
|
124
|
+
userId: string;
|
|
125
|
+
conversationId: string;
|
|
126
|
+
status: string;
|
|
127
|
+
userData?: unknown;
|
|
128
|
+
};
|
|
129
|
+
'presence:state': {
|
|
130
|
+
conversationId: string;
|
|
131
|
+
members: PresenceMember[];
|
|
132
|
+
};
|
|
133
|
+
'read': {
|
|
134
|
+
userId: string;
|
|
135
|
+
conversationId: string;
|
|
136
|
+
lastReadAt: string;
|
|
137
|
+
};
|
|
138
|
+
'reaction': {
|
|
139
|
+
reaction: ChatReaction;
|
|
140
|
+
conversationId: string;
|
|
141
|
+
};
|
|
142
|
+
'delivery': {
|
|
143
|
+
messageId: string;
|
|
144
|
+
status: 'sent' | 'delivered' | 'read';
|
|
145
|
+
};
|
|
146
|
+
'error': {
|
|
147
|
+
code: string;
|
|
148
|
+
message: string;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
|
|
152
|
+
interface SendMessageOptions {
|
|
153
|
+
content: string;
|
|
154
|
+
message_type?: 'text' | 'image' | 'file';
|
|
155
|
+
attachments?: Attachment[];
|
|
156
|
+
}
|
|
157
|
+
interface ListConversationsOptions {
|
|
158
|
+
page?: number;
|
|
159
|
+
per_page?: number;
|
|
160
|
+
}
|
|
161
|
+
interface GetMessagesOptions {
|
|
162
|
+
limit?: number;
|
|
163
|
+
before?: string;
|
|
164
|
+
after?: string;
|
|
165
|
+
}
|
|
166
|
+
interface CreateConversationOptions {
|
|
167
|
+
conversation_type?: 'direct' | 'group';
|
|
168
|
+
name?: string;
|
|
169
|
+
participant_ids: string[];
|
|
170
|
+
}
|
|
171
|
+
interface MessagesResponse {
|
|
172
|
+
messages: ChatMessage[];
|
|
173
|
+
has_more?: boolean;
|
|
174
|
+
oldest_id?: string;
|
|
175
|
+
newest_id?: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export type { ApiError as A, ChannelSettings as C, GetMessagesOptions as G, ListConversationsOptions as L, MessagesResponse as M, Participant as P, ReadStatus as R, SendMessageOptions as S, ApiResponse as a, Attachment as b, ChatConfig as c, ChatEventMap as d, ChatMessage as e, ChatReaction as f, ConnectionStatus as g, Conversation as h, CreateConversationOptions as i, PresenceMember as j };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
interface ChatConfig {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
embedToken?: string;
|
|
4
|
+
apiBaseUrl?: string;
|
|
5
|
+
applicationId?: string;
|
|
6
|
+
userId?: string;
|
|
7
|
+
sessionToken?: string;
|
|
8
|
+
getToken?: () => Promise<string | null>;
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
reconnect?: {
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
baseDelay?: number;
|
|
13
|
+
maxDelay?: number;
|
|
14
|
+
};
|
|
15
|
+
messageCache?: {
|
|
16
|
+
maxMessages?: number;
|
|
17
|
+
maxConversations?: number;
|
|
18
|
+
};
|
|
19
|
+
offlineQueue?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ApiResponse<T> {
|
|
22
|
+
data: T | null;
|
|
23
|
+
error: ApiError | null;
|
|
24
|
+
}
|
|
25
|
+
interface ApiError {
|
|
26
|
+
code: string;
|
|
27
|
+
message: string;
|
|
28
|
+
status: number;
|
|
29
|
+
details?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
interface Conversation {
|
|
32
|
+
id: string;
|
|
33
|
+
conversation_type: 'direct' | 'group' | 'broadcast' | 'ephemeral' | 'large_room';
|
|
34
|
+
name?: string;
|
|
35
|
+
created_by?: string;
|
|
36
|
+
participant_count?: number;
|
|
37
|
+
last_message_at?: string;
|
|
38
|
+
unread_count?: number;
|
|
39
|
+
created_at: string;
|
|
40
|
+
participants?: Participant[];
|
|
41
|
+
}
|
|
42
|
+
interface Participant {
|
|
43
|
+
user_id: string;
|
|
44
|
+
role: string;
|
|
45
|
+
joined_at: string;
|
|
46
|
+
}
|
|
47
|
+
interface ChatMessage {
|
|
48
|
+
id: string;
|
|
49
|
+
content: string;
|
|
50
|
+
message_type: 'text' | 'image' | 'file' | 'system';
|
|
51
|
+
sender_id: string;
|
|
52
|
+
sender_type?: string;
|
|
53
|
+
sender_agent_model?: string;
|
|
54
|
+
attachments?: Attachment[];
|
|
55
|
+
is_edited: boolean;
|
|
56
|
+
created_at: string;
|
|
57
|
+
}
|
|
58
|
+
interface Attachment {
|
|
59
|
+
file_id: string;
|
|
60
|
+
file_name: string;
|
|
61
|
+
file_size: number;
|
|
62
|
+
mime_type: string;
|
|
63
|
+
presigned_url?: string;
|
|
64
|
+
thumbnail_url?: string;
|
|
65
|
+
}
|
|
66
|
+
interface ReadStatus {
|
|
67
|
+
user_id: string;
|
|
68
|
+
last_read_at?: string;
|
|
69
|
+
}
|
|
70
|
+
interface ChatReaction {
|
|
71
|
+
id: string;
|
|
72
|
+
message_id: string;
|
|
73
|
+
user_id: string;
|
|
74
|
+
emoji: string;
|
|
75
|
+
}
|
|
76
|
+
interface PresenceMember {
|
|
77
|
+
user_id: string;
|
|
78
|
+
user_data?: unknown;
|
|
79
|
+
joined_at: string;
|
|
80
|
+
}
|
|
81
|
+
interface ChannelSettings {
|
|
82
|
+
publisher_user_ids?: string[];
|
|
83
|
+
linked_session_id?: string;
|
|
84
|
+
expires_at?: string;
|
|
85
|
+
max_participants?: number;
|
|
86
|
+
slow_mode_seconds?: number;
|
|
87
|
+
}
|
|
88
|
+
interface ChatEventMap {
|
|
89
|
+
connected: void;
|
|
90
|
+
disconnected: void;
|
|
91
|
+
reconnecting: {
|
|
92
|
+
attempt: number;
|
|
93
|
+
};
|
|
94
|
+
'message': {
|
|
95
|
+
message: ChatMessage;
|
|
96
|
+
conversationId: string;
|
|
97
|
+
};
|
|
98
|
+
'message:updated': {
|
|
99
|
+
message: ChatMessage;
|
|
100
|
+
conversationId: string;
|
|
101
|
+
};
|
|
102
|
+
'message:deleted': {
|
|
103
|
+
messageId: string;
|
|
104
|
+
conversationId: string;
|
|
105
|
+
};
|
|
106
|
+
'typing': {
|
|
107
|
+
userId: string;
|
|
108
|
+
conversationId: string;
|
|
109
|
+
};
|
|
110
|
+
'typing:stop': {
|
|
111
|
+
userId: string;
|
|
112
|
+
conversationId: string;
|
|
113
|
+
};
|
|
114
|
+
'presence:join': {
|
|
115
|
+
userId: string;
|
|
116
|
+
conversationId: string;
|
|
117
|
+
userData?: unknown;
|
|
118
|
+
};
|
|
119
|
+
'presence:leave': {
|
|
120
|
+
userId: string;
|
|
121
|
+
conversationId: string;
|
|
122
|
+
};
|
|
123
|
+
'presence:update': {
|
|
124
|
+
userId: string;
|
|
125
|
+
conversationId: string;
|
|
126
|
+
status: string;
|
|
127
|
+
userData?: unknown;
|
|
128
|
+
};
|
|
129
|
+
'presence:state': {
|
|
130
|
+
conversationId: string;
|
|
131
|
+
members: PresenceMember[];
|
|
132
|
+
};
|
|
133
|
+
'read': {
|
|
134
|
+
userId: string;
|
|
135
|
+
conversationId: string;
|
|
136
|
+
lastReadAt: string;
|
|
137
|
+
};
|
|
138
|
+
'reaction': {
|
|
139
|
+
reaction: ChatReaction;
|
|
140
|
+
conversationId: string;
|
|
141
|
+
};
|
|
142
|
+
'delivery': {
|
|
143
|
+
messageId: string;
|
|
144
|
+
status: 'sent' | 'delivered' | 'read';
|
|
145
|
+
};
|
|
146
|
+
'error': {
|
|
147
|
+
code: string;
|
|
148
|
+
message: string;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
|
|
152
|
+
interface SendMessageOptions {
|
|
153
|
+
content: string;
|
|
154
|
+
message_type?: 'text' | 'image' | 'file';
|
|
155
|
+
attachments?: Attachment[];
|
|
156
|
+
}
|
|
157
|
+
interface ListConversationsOptions {
|
|
158
|
+
page?: number;
|
|
159
|
+
per_page?: number;
|
|
160
|
+
}
|
|
161
|
+
interface GetMessagesOptions {
|
|
162
|
+
limit?: number;
|
|
163
|
+
before?: string;
|
|
164
|
+
after?: string;
|
|
165
|
+
}
|
|
166
|
+
interface CreateConversationOptions {
|
|
167
|
+
conversation_type?: 'direct' | 'group';
|
|
168
|
+
name?: string;
|
|
169
|
+
participant_ids: string[];
|
|
170
|
+
}
|
|
171
|
+
interface MessagesResponse {
|
|
172
|
+
messages: ChatMessage[];
|
|
173
|
+
has_more?: boolean;
|
|
174
|
+
oldest_id?: string;
|
|
175
|
+
newest_id?: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export type { ApiError as A, ChannelSettings as C, GetMessagesOptions as G, ListConversationsOptions as L, MessagesResponse as M, Participant as P, ReadStatus as R, SendMessageOptions as S, ApiResponse as a, Attachment as b, ChatConfig as c, ChatEventMap as d, ChatMessage as e, ChatReaction as f, ConnectionStatus as g, Conversation as h, CreateConversationOptions as i, PresenceMember as j };
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scalemule/chat",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "ScaleMule standalone chat SDK — real-time messaging, presence, typing indicators",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./react": {
|
|
16
|
+
"types": "./dist/react.d.ts",
|
|
17
|
+
"import": "./dist/react.js",
|
|
18
|
+
"require": "./dist/react.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./element": {
|
|
21
|
+
"types": "./dist/element.d.ts",
|
|
22
|
+
"import": "./dist/element.js",
|
|
23
|
+
"require": "./dist/element.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./iframe": {
|
|
26
|
+
"types": "./dist/iframe.d.ts",
|
|
27
|
+
"import": "./dist/iframe.js",
|
|
28
|
+
"require": "./dist/iframe.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup",
|
|
38
|
+
"dev": "tsup --watch",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"lint": "eslint src/",
|
|
41
|
+
"test": "vitest run --passWithNoTests",
|
|
42
|
+
"test:watch": "vitest"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react": ">=17.0.0",
|
|
46
|
+
"react-dom": ">=17.0.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependenciesMeta": {
|
|
49
|
+
"react": { "optional": true },
|
|
50
|
+
"react-dom": { "optional": true }
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/react": "^18.0.0",
|
|
54
|
+
"@types/react-dom": "^18.0.0",
|
|
55
|
+
"tsup": "^8.0.0",
|
|
56
|
+
"typescript": "^5.4.0",
|
|
57
|
+
"vitest": "^2.0.0"
|
|
58
|
+
},
|
|
59
|
+
"author": "ScaleMule Inc. <support@scalemule.com>",
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=18.0.0"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public",
|
|
66
|
+
"registry": "https://registry.npmjs.org/"
|
|
67
|
+
}
|
|
68
|
+
}
|