@xcelsior/ui-chat 2.0.2 → 2.0.3

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/index.d.mts CHANGED
@@ -310,6 +310,9 @@ interface UseWebSocketReturn {
310
310
  /**
311
311
  * Hook for WebSocket connection in chat widget.
312
312
  * Can use an external WebSocket connection (for agents) via the externalWebSocket prop.
313
+ *
314
+ * Handles React Strict Mode (dev) gracefully — tracks whether the effect has been
315
+ * cleaned up so that an aborted connection doesn't trigger reconnection.
313
316
  */
314
317
  declare function useWebSocket(config: IChatConfig, externalWebSocket?: WebSocket | null): UseWebSocketReturn;
315
318
 
package/dist/index.d.ts CHANGED
@@ -310,6 +310,9 @@ interface UseWebSocketReturn {
310
310
  /**
311
311
  * Hook for WebSocket connection in chat widget.
312
312
  * Can use an external WebSocket connection (for agents) via the externalWebSocket prop.
313
+ *
314
+ * Handles React Strict Mode (dev) gracefully — tracks whether the effect has been
315
+ * cleaned up so that an aborted connection doesn't trigger reconnection.
313
316
  */
314
317
  declare function useWebSocket(config: IChatConfig, externalWebSocket?: WebSocket | null): UseWebSocketReturn;
315
318
 
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ function useWebSocket(config, externalWebSocket) {
62
62
  const reconnectTimeoutRef = (0, import_react.useRef)(null);
63
63
  const reconnectAttemptsRef = (0, import_react.useRef)(0);
64
64
  const messageHandlerRef = (0, import_react.useRef)(null);
65
+ const abortedRef = (0, import_react.useRef)(false);
65
66
  const maxReconnectAttempts = 5;
66
67
  const reconnectDelay = 3e3;
67
68
  const isUsingExternalWs = !!externalWebSocket;
@@ -94,6 +95,7 @@ function useWebSocket(config, externalWebSocket) {
94
95
  };
95
96
  }, []);
96
97
  const connect = (0, import_react.useCallback)(() => {
98
+ if (abortedRef.current) return;
97
99
  console.log("connecting to WebSocket...", config.currentUser, config.conversationId);
98
100
  try {
99
101
  if (wsRef.current) {
@@ -113,6 +115,10 @@ function useWebSocket(config, externalWebSocket) {
113
115
  }
114
116
  const ws = new WebSocket(url.toString());
115
117
  ws.onopen = () => {
118
+ if (abortedRef.current) {
119
+ ws.close(1e3, "Effect cleaned up");
120
+ return;
121
+ }
116
122
  console.log("WebSocket connected");
117
123
  setIsConnected(true);
118
124
  setError(null);
@@ -120,12 +126,14 @@ function useWebSocket(config, externalWebSocket) {
120
126
  config.onConnectionChange?.(true);
121
127
  };
122
128
  ws.onerror = (event) => {
129
+ if (abortedRef.current) return;
123
130
  console.error("WebSocket error:", event);
124
131
  const err = new Error("WebSocket connection error");
125
132
  setError(err);
126
133
  config.onError?.(err);
127
134
  };
128
135
  ws.onclose = (event) => {
136
+ if (abortedRef.current) return;
129
137
  console.log("WebSocket closed:", event.code, event.reason);
130
138
  setIsConnected(false);
131
139
  config.onConnectionChange?.(false);
@@ -174,6 +182,7 @@ function useWebSocket(config, externalWebSocket) {
174
182
  );
175
183
  const reconnect = (0, import_react.useCallback)(() => {
176
184
  reconnectAttemptsRef.current = 0;
185
+ abortedRef.current = false;
177
186
  connect();
178
187
  }, [connect]);
179
188
  (0, import_react.useEffect)(() => {
@@ -183,8 +192,10 @@ function useWebSocket(config, externalWebSocket) {
183
192
  const cleanup = subscribeToMessage(externalWebSocket);
184
193
  return cleanup;
185
194
  }
195
+ abortedRef.current = false;
186
196
  connect();
187
197
  return () => {
198
+ abortedRef.current = true;
188
199
  if (reconnectTimeoutRef.current) {
189
200
  clearTimeout(reconnectTimeoutRef.current);
190
201
  }