@tracktor/shared-module 2.22.1 → 2.24.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
 
@@ -38,10 +39,11 @@ export default App;
38
39
  ```
39
40
 
40
41
  ## Providers
41
- | Module | Description | Dependencies |
42
- |-------------------------------|------------------------------------------------|--------------|
43
- | InjectDependenciesProvider | Inject dependencies for other shared component | - |
44
- | QueryClientProviderWithConfig | React Query provider with default config | React Query |
42
+ | Module | Description | Dependencies |
43
+ |-------------------------------|-----------------------------------------------------|--------------|
44
+ | InjectDependenciesProvider | Inject dependencies for other shared component | - |
45
+ | QueryClientProviderWithConfig | React Query provider with default config | React Query |
46
+ | ChatProvider | Shared WebSocket chat connection provider via context | - |
45
47
 
46
48
 
47
49
  ## Components
@@ -65,6 +67,77 @@ export default App;
65
67
  | useInfiniteDataGrid | This hook is used to handle the infinite scroll of the DataGrid component. | - |
66
68
  | useCurrentLanguage | This get the current language of app | - |
67
69
  | useFilters | Hook to handle filter | - |
70
+ | useChat | Hook to consume the ChatProvider context (threads, messaging, presence) | ChatProvider |
71
+
72
+
73
+ ## WebSocket
74
+
75
+ 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.
76
+
77
+ **With the React provider** (recommended):
78
+
79
+ First, wrap your app with `ChatProvider` (inside `InjectDependenciesProvider`):
80
+
81
+ ```typescript jsx
82
+ import { ChatProvider, InjectDependenciesProvider } from "@tracktor/shared-module";
83
+
84
+ const App = () => (
85
+ <InjectDependenciesProvider apiURL={import.meta.env.VITE_API_URL} libraries={libraries} localStorageKeys={localStorageKeys}>
86
+ <ChatProvider>
87
+ <MyApp />
88
+ </ChatProvider>
89
+ </InjectDependenciesProvider>
90
+ );
91
+ ```
92
+
93
+ Then use `useChat()` in any component:
94
+
95
+ ```typescript jsx
96
+ import { useChat } from "@tracktor/shared-module";
97
+
98
+ const Chat = ({ threadId }: { threadId: string }) => {
99
+ const { isReady, sendMessage, joinThread } = useChat();
100
+
101
+ return (
102
+ <div>
103
+ <p>{isReady ? "Connected" : "Connecting..."}</p>
104
+ <button onClick={() => joinThread(threadId)}>Join</button>
105
+ <button onClick={() => sendMessage(threadId, "Hello!")}>Send</button>
106
+ </div>
107
+ );
108
+ };
109
+ ```
110
+
111
+ The provider reads `apiURL` and the user token from `InjectDependenciesProvider` automatically. You can override both via props:
112
+
113
+ ```typescript jsx
114
+ <ChatProvider url="wss://app.api.dev.tracktor.fr/v2/threads/ws" token="my-jwt">
115
+ ```
116
+
117
+ **Without React** (class only):
118
+
119
+ ```typescript
120
+ import { ChatClient } from "@tracktor/shared-module";
121
+
122
+ const client = new ChatClient({
123
+ url: "wss://app.api.dev.tracktor.fr/v2/threads/ws",
124
+ getToken: () => "my-jwt",
125
+ onEvent: (event) => console.log(event),
126
+ onConnectionChange: (connected) => console.log("connected:", connected),
127
+ });
128
+
129
+ client.connect();
130
+ client.joinThread("thread-1");
131
+ client.sendMessage("thread-1", "Hello!");
132
+ ```
133
+
134
+ ### Chat WebSocket
135
+ | Module | Description | Dependencies |
136
+ |------------|-----------------------------------------------------------|--------------|
137
+ | ChatClient | Framework-agnostic WebSocket client for the chat protocol | - |
138
+ | ChatProvider | Provider for shared WebSocket connection via context | - |
139
+ | useChat | React hook to consume the ChatProvider context | ChatProvider |
140
+
68
141
 
69
142
  ## Config
70
143
  | 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,14 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { UseChatParams } from '../chat/types';
3
+ export interface ChatContextValue {
4
+ isConnected: boolean;
5
+ isReady: boolean;
6
+ joinThread: (threadId: string) => void;
7
+ leaveThread: (threadId: string) => void;
8
+ listThreads: (limit?: number, offset?: number) => void;
9
+ markRead: (threadId: string) => void;
10
+ sendMessage: (threadId: string, body: string) => void;
11
+ }
12
+ export declare const ChatContext: import('react').Context<ChatContextValue | null>;
13
+ declare const ChatProvider: ({ children, ...params }: PropsWithChildren<UseChatParams>) => import("react/jsx-runtime").JSX.Element;
14
+ export default ChatProvider;
@@ -0,0 +1,8 @@
1
+ import { ChatContextValue } from '../context/ChatProvider';
2
+ /**
3
+ * Hook to access the shared WebSocket chat connection.
4
+ * Provides methods to join/leave threads, send messages, mark as read, and list threads.
5
+ * Must be used within a ChatProvider.
6
+ */
7
+ export declare const useChat: () => ChatContextValue;
8
+ 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';
@@ -17,6 +19,8 @@ export * from './components/Utils/RequireAuth';
17
19
  export { default as RequireAuth } from './components/Utils/RequireAuth';
18
20
  export * from './config/orval';
19
21
  export { default as getOrvalConfig } from './config/orval';
22
+ export * from './context/ChatProvider';
23
+ export { default as ChatProvider } from './context/ChatProvider';
20
24
  export * from './context/InjectDependenciesProvider';
21
25
  export { default as InjectDependenciesProvider } from './context/InjectDependenciesProvider';
22
26
  export * from './context/QueryClientProviderWithConfig';
@@ -25,6 +29,8 @@ export * from './hooks/useAdapter';
25
29
  export { default as useAdapter } from './hooks/useAdapter';
26
30
  export * from './hooks/useAuth';
27
31
  export { default as useAuth } from './hooks/useAuth';
32
+ export * from './hooks/useChat';
33
+ export { default as useChat } from './hooks/useChat';
28
34
  export * from './hooks/useCurrentLanguage/useCurrentLanguage';
29
35
  export { default as useCurrentLanguage } from './hooks/useCurrentLanguage/useCurrentLanguage';
30
36
  export * from './hooks/useFilters';