@tracktor/shared-module 2.22.1 → 2.23.0

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
@@ -7,6 +7,7 @@
7
7
  - [Installation](#Installation)
8
8
  - [Usage](#Usage)
9
9
  - [Inject dependencies with provider](#Inject-dependencies-with-provider)
10
+ - [WebSocket](#WebSocket)
10
11
 
11
12
  ## Installation
12
13
 
@@ -65,6 +66,62 @@ export default App;
65
66
  | useInfiniteDataGrid | This hook is used to handle the infinite scroll of the DataGrid component. | - |
66
67
  | useCurrentLanguage | This get the current language of app | - |
67
68
  | useFilters | Hook to handle filter | - |
69
+ | useChat | Hook for chat WebSocket connection (threads, messaging, presence) | - |
70
+
71
+
72
+ ## WebSocket
73
+
74
+ The chat module provides a WebSocket client for the Tracktor chat protocol (`/v2/threads/ws`). It supports thread subscription, messaging, read receipts, and presence events.
75
+
76
+ **With the React hook** (recommended):
77
+
78
+ ```typescript jsx
79
+ import { useChat } from "@tracktor/shared-module";
80
+
81
+ const Chat = ({ threadId }: { threadId: string }) => {
82
+ const { isReady, sendMessage, joinThread } = useChat({
83
+ onNewMessage: (event) => console.log("New message:", event.message),
84
+ });
85
+
86
+ return (
87
+ <div>
88
+ <p>{isReady ? "Connected" : "Connecting..."}</p>
89
+ <button onClick={() => joinThread(threadId)}>Join</button>
90
+ <button onClick={() => sendMessage(threadId, "Hello!")}>Send</button>
91
+ </div>
92
+ );
93
+ };
94
+ ```
95
+
96
+ The hook reads `apiURL` and the user token from `InjectDependenciesProvider` automatically. You can override both via props:
97
+
98
+ ```typescript jsx
99
+ useChat({ url: "wss://app.api.dev.tracktor.fr/v2/threads/ws", token: "my-jwt" });
100
+ ```
101
+
102
+ **Without React** (class only):
103
+
104
+ ```typescript
105
+ import { ChatClient } from "@tracktor/shared-module";
106
+
107
+ const client = new ChatClient({
108
+ url: "wss://app.api.dev.tracktor.fr/v2/threads/ws",
109
+ getToken: () => "my-jwt",
110
+ onEvent: (event) => console.log(event),
111
+ onConnectionChange: (connected) => console.log("connected:", connected),
112
+ });
113
+
114
+ client.connect();
115
+ client.joinThread("thread-1");
116
+ client.sendMessage("thread-1", "Hello!");
117
+ ```
118
+
119
+ ### Chat WebSocket
120
+ | Module | Description | Dependencies |
121
+ |------------|-----------------------------------------------------------|--------------|
122
+ | ChatClient | Framework-agnostic WebSocket client for the chat protocol | - |
123
+ | useChat | React hook wrapping ChatClient | - |
124
+
68
125
 
69
126
  ## Config
70
127
  | Module | Description |
@@ -0,0 +1,34 @@
1
+ import { ChatClientOptions } from './types';
2
+ declare class ChatClient {
3
+ private readonly url;
4
+ private readonly getToken;
5
+ private readonly onEvent?;
6
+ private readonly onConnectionChange?;
7
+ private readonly shouldReconnect;
8
+ private readonly maxReconnectAttempts;
9
+ private readonly reconnectBaseDelay;
10
+ private ws;
11
+ private reconnectAttempt;
12
+ private reconnectTimer;
13
+ private intentionalClose;
14
+ private joinedThreads;
15
+ private pendingMessages;
16
+ private _connected;
17
+ private _ready;
18
+ constructor(options: ChatClientOptions);
19
+ get connected(): boolean;
20
+ get ready(): boolean;
21
+ connect(): void;
22
+ disconnect(): void;
23
+ joinThread(threadId: string): void;
24
+ leaveThread(threadId: string): void;
25
+ sendMessage(threadId: string, body: string): void;
26
+ markRead(threadId: string): void;
27
+ listThreads(limit?: number, offset?: number): void;
28
+ private send;
29
+ private flushPendingMessages;
30
+ private rejoinThreads;
31
+ private scheduleReconnect;
32
+ private clearReconnectTimer;
33
+ }
34
+ export default ChatClient;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,105 @@
1
+ export interface Thread {
2
+ id: string;
3
+ participants: string[];
4
+ lastMessage?: Message;
5
+ unreadCount?: number;
6
+ createdAt: string;
7
+ updatedAt: string;
8
+ }
9
+ export interface Message {
10
+ id: string;
11
+ threadId: string;
12
+ senderId: string;
13
+ body: string;
14
+ createdAt: string;
15
+ }
16
+ export interface JoinThread {
17
+ type: "join_thread";
18
+ threadId: string;
19
+ }
20
+ export interface LeaveThread {
21
+ type: "leave_thread";
22
+ threadId: string;
23
+ }
24
+ export interface SendMessage {
25
+ type: "send_message";
26
+ threadId: string;
27
+ body: string;
28
+ }
29
+ export interface MarkRead {
30
+ type: "mark_read";
31
+ threadId: string;
32
+ }
33
+ export interface ListThreads {
34
+ type: "list_threads";
35
+ limit?: number;
36
+ offset?: number;
37
+ }
38
+ export type ClientMessage = JoinThread | LeaveThread | SendMessage | MarkRead | ListThreads;
39
+ export interface ReadyEvent {
40
+ type: "ready";
41
+ userId: string;
42
+ }
43
+ export interface JoinedThread {
44
+ type: "joined_thread";
45
+ threadId: string;
46
+ thread: Thread;
47
+ }
48
+ export interface LeftThread {
49
+ type: "left_thread";
50
+ threadId: string;
51
+ }
52
+ export interface NewMessageEvent {
53
+ type: "new_message";
54
+ message: Message;
55
+ }
56
+ export interface NewMessageNotification {
57
+ type: "new_message_notification";
58
+ threadId: string;
59
+ message: Message;
60
+ }
61
+ export interface MarkedRead {
62
+ type: "marked_read";
63
+ threadId: string;
64
+ userId: string;
65
+ }
66
+ export interface ThreadsListEvent {
67
+ type: "threads_list";
68
+ threads: Thread[];
69
+ total: number;
70
+ }
71
+ export interface PresenceEvent {
72
+ type: "presence";
73
+ userId: string;
74
+ online: boolean;
75
+ }
76
+ export interface ErrorEvent {
77
+ type: "error";
78
+ code: string;
79
+ message: string;
80
+ }
81
+ export type ServerEvent = ReadyEvent | JoinedThread | LeftThread | NewMessageEvent | NewMessageNotification | MarkedRead | ThreadsListEvent | PresenceEvent | ErrorEvent;
82
+ export interface ChatClientOptions {
83
+ url: string;
84
+ getToken: () => string | null;
85
+ onEvent?: (event: ServerEvent) => void;
86
+ onConnectionChange?: (connected: boolean) => void;
87
+ reconnect?: boolean;
88
+ maxReconnectAttempts?: number;
89
+ reconnectBaseDelay?: number;
90
+ }
91
+ export interface UseChatParams {
92
+ token?: string;
93
+ url?: string;
94
+ enabled?: boolean;
95
+ reconnect?: boolean;
96
+ onReady?: (event: ReadyEvent) => void;
97
+ onNewMessage?: (event: NewMessageEvent) => void;
98
+ onNewMessageNotification?: (event: NewMessageNotification) => void;
99
+ onPresence?: (event: PresenceEvent) => void;
100
+ onError?: (event: ErrorEvent) => void;
101
+ onJoinedThread?: (event: JoinedThread) => void;
102
+ onLeftThread?: (event: LeftThread) => void;
103
+ onMarkedRead?: (event: MarkedRead) => void;
104
+ onThreadsList?: (event: ThreadsListEvent) => void;
105
+ }
@@ -0,0 +1,11 @@
1
+ import { UseChatParams } from '../chat/types';
2
+ export declare const useChat: (params?: UseChatParams) => {
3
+ isConnected: boolean;
4
+ isReady: boolean;
5
+ joinThread: (threadId: string) => void;
6
+ leaveThread: (threadId: string) => void;
7
+ listThreads: (limit?: number, offset?: number) => void;
8
+ markRead: (threadId: string) => void;
9
+ sendMessage: (threadId: string, body: string) => void;
10
+ };
11
+ export default useChat;
package/dist/main.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { axiosCustomInstance, type BodyType, type ErrorType } from './axios/axiosCustomInstance';
2
+ export { default as ChatClient } from './chat/ChatClient';
3
+ export * from './chat/types';
2
4
  export * from './components/Inputs/MaskTextField';
3
5
  export { default as MaskTextField } from './components/Inputs/MaskTextField';
4
6
  export * from './components/Utils/GTMSendPageView';
@@ -25,6 +27,8 @@ export * from './hooks/useAdapter';
25
27
  export { default as useAdapter } from './hooks/useAdapter';
26
28
  export * from './hooks/useAuth';
27
29
  export { default as useAuth } from './hooks/useAuth';
30
+ export * from './hooks/useChat';
31
+ export { default as useChat } from './hooks/useChat';
28
32
  export * from './hooks/useCurrentLanguage/useCurrentLanguage';
29
33
  export { default as useCurrentLanguage } from './hooks/useCurrentLanguage/useCurrentLanguage';
30
34
  export * from './hooks/useFilters';