@gobolt/genesis 0.3.2 → 0.3.4

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.
@@ -13,6 +13,7 @@ export interface ChatProps {
13
13
  messageHistory: Array<Message>;
14
14
  title?: string;
15
15
  isSimulated?: boolean;
16
+ authToken?: string;
16
17
  }
17
18
  declare const Chat: FC<ChatProps>;
18
19
  export default Chat;
@@ -3,6 +3,7 @@ interface MessageProps {
3
3
  message: string;
4
4
  handle: string;
5
5
  isThinking?: boolean;
6
+ id?: string;
6
7
  }
7
8
  declare const Message: FC<MessageProps>;
8
9
  export default Message;
@@ -14,6 +14,8 @@ declare const meta: {
14
14
  };
15
15
  export default meta;
16
16
  type Story = StoryObj<typeof meta>;
17
- export declare const Default: Story;
17
+ export declare const local: Story;
18
+ export declare const remote: Story;
18
19
  export declare const WithMessageHistory: Story;
19
20
  export declare const WithTitle: Story;
21
+ export declare const Remote: Story;
package/dist/index.cjs CHANGED
@@ -74920,20 +74920,7 @@ const Message$1 = ({ message: message2, handle, isThinking = false }) => {
74920
74920
  const isBot = handle === "bot";
74921
74921
  return /* @__PURE__ */ jsxRuntime.jsxs(MessageContainer, { $isBot: isBot, children: [
74922
74922
  /* @__PURE__ */ jsxRuntime.jsx(IconContainer, { children: isBot ? /* @__PURE__ */ jsxRuntime.jsx(BotIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(UserIcon, {}) }),
74923
- /* @__PURE__ */ jsxRuntime.jsx(TextContainer, { $isBot: isBot, children: isThinking ? /* @__PURE__ */ jsxRuntime.jsx(ThinkingIndicator, {}) : handle === "bot" ? /* @__PURE__ */ jsxRuntime.jsx(
74924
- Markdown,
74925
- {
74926
- components: {
74927
- p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 last:mb-0", children }),
74928
- ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc pl-4 mb-2", children }),
74929
- ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal pl-4 mb-2", children }),
74930
- li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "mb-1", children }),
74931
- code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { className: "bg-gray-200 rounded px-1 py-0.5", children }),
74932
- pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "bg-gray-200 rounded p-2 mb-2 overflow-x-auto", children })
74933
- },
74934
- children: message2
74935
- }
74936
- ) : /* @__PURE__ */ jsxRuntime.jsx(MessageText, { children: message2 }) })
74923
+ /* @__PURE__ */ jsxRuntime.jsx(TextContainer, { $isBot: isBot, children: isThinking ? /* @__PURE__ */ jsxRuntime.jsx(ThinkingIndicator, {}) : handle === "bot" ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: message2 }) : /* @__PURE__ */ jsxRuntime.jsx(MessageText, { children: message2 }) })
74937
74924
  ] });
74938
74925
  };
74939
74926
  const getStateColors = (colors2, type4, state) => {
@@ -75349,7 +75336,7 @@ const ChatContainer = styled.div`
75349
75336
  display: flex;
75350
75337
  flex-direction: column;
75351
75338
  position: relative;
75352
- width: 540px;
75339
+ width: 600px;
75353
75340
  overflow: hidden;
75354
75341
  `;
75355
75342
  const HeroContainer = styled.div`
@@ -75399,7 +75386,8 @@ const Chat = ({
75399
75386
  isOpen = false,
75400
75387
  messageHistory = [],
75401
75388
  title = null,
75402
- isSimulated = false
75389
+ isSimulated = false,
75390
+ authToken
75403
75391
  }) => {
75404
75392
  const [isChatOpen, setIsChatOpen] = React.useState(isOpen);
75405
75393
  const [message2, setMessage] = React.useState("");
@@ -75413,80 +75401,133 @@ const Chat = ({
75413
75401
  const [isLocked, setIsLocked] = React.useState(false);
75414
75402
  React.useEffect(() => {
75415
75403
  if (isSimulated) return;
75416
- console.log("Connecting to socket server at:", socketUrl);
75417
- socketRef.current = lookup(socketUrl, {
75418
- extraHeaders: {
75419
- "Access-Control-Allow-Origin": "*"
75420
- }
75421
- });
75422
- const socket = socketRef.current;
75423
- socket.on("connect", () => {
75424
- console.log("Socket connected successfully");
75425
- });
75426
- socket.on("connect_error", (error2) => {
75427
- console.error("Socket connection error:", error2);
75428
- setServerError("Failed to connect to server");
75429
- setServerStatus("error");
75430
- serverReadyRef.current = false;
75431
- });
75432
- socket.on("new connection", () => {
75433
- console.log("New connection established");
75434
- });
75435
- socket.on("server-ready", () => {
75436
- console.log("Server is ready");
75437
- setServerError("");
75438
- setServerStatus("ready");
75439
- serverReadyRef.current = true;
75440
- });
75441
- socket.on("message", (newMessage) => {
75442
- setMessages((prev2) => {
75443
- if (newMessage.sender === "bot") {
75444
- let replaced = false;
75445
- const updated = prev2.map((msg) => {
75446
- if (msg.isThinking && !replaced) {
75447
- replaced = true;
75448
- return { ...newMessage, isThinking: false };
75404
+ const socketUrlToUse = window.location.hostname === "localhost" && window.location.port === "6006" ? "http://localhost:3000" : socketUrl;
75405
+ console.log("Connecting to socket server at:", socketUrlToUse);
75406
+ const validateToken = async () => {
75407
+ try {
75408
+ const response = await fetch(
75409
+ "https://www.googleapis.com/oauth2/v2/userinfo",
75410
+ {
75411
+ headers: {
75412
+ Authorization: `Bearer ${authToken}`
75449
75413
  }
75450
- return msg;
75414
+ }
75415
+ );
75416
+ if (!response.ok) {
75417
+ throw new Error("Invalid token");
75418
+ }
75419
+ socketRef.current = lookup(socketUrlToUse, {
75420
+ transports: ["polling", "websocket"],
75421
+ reconnection: true,
75422
+ reconnectionAttempts: 5,
75423
+ reconnectionDelay: 1e3,
75424
+ withCredentials: true,
75425
+ forceNew: true,
75426
+ autoConnect: true,
75427
+ timeout: 1e4,
75428
+ auth: {
75429
+ token: authToken,
75430
+ type: "Bearer"
75431
+ }
75432
+ });
75433
+ const socket = socketRef.current;
75434
+ socket.on("connect", () => {
75435
+ console.log("Socket connected successfully");
75436
+ setServerError("");
75437
+ setServerStatus("ready");
75438
+ serverReadyRef.current = true;
75439
+ });
75440
+ socket.on("connect_error", (error2) => {
75441
+ console.error("Socket connection error:", error2);
75442
+ setServerError(`Connection error: ${error2.message}`);
75443
+ setServerStatus("error");
75444
+ serverReadyRef.current = false;
75445
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75446
+ setIsLocked(false);
75447
+ });
75448
+ socket.on("disconnect", (reason) => {
75449
+ console.log("Socket disconnected:", reason);
75450
+ setServerError(`Disconnected: ${reason}`);
75451
+ setServerStatus("error");
75452
+ serverReadyRef.current = false;
75453
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75454
+ setIsLocked(false);
75455
+ });
75456
+ socket.on("new connection", () => {
75457
+ console.log("New connection established");
75458
+ });
75459
+ socket.on("server-ready", () => {
75460
+ console.log("Server is ready");
75461
+ setServerError("");
75462
+ setServerStatus("ready");
75463
+ serverReadyRef.current = true;
75464
+ });
75465
+ socket.on("message", (newMessage) => {
75466
+ setMessages((prev2) => {
75467
+ if (newMessage.sender === "bot") {
75468
+ if (newMessage.content === "Processing your message...") {
75469
+ const hasThinkingMessage = prev2.some((msg) => msg.isThinking);
75470
+ if (hasThinkingMessage) {
75471
+ return prev2;
75472
+ }
75473
+ return [...prev2, { ...newMessage, isThinking: true }];
75474
+ }
75475
+ const thinkingMessage = prev2.find((msg) => msg.isThinking);
75476
+ if (thinkingMessage) {
75477
+ return prev2.map(
75478
+ (msg) => msg.isThinking ? { ...newMessage, isThinking: false } : msg
75479
+ );
75480
+ }
75481
+ return [...prev2, { ...newMessage, isThinking: false }];
75482
+ }
75483
+ const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75484
+ if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75485
+ return prev2;
75486
+ }
75487
+ return [...prev2, newMessage];
75451
75488
  });
75452
75489
  setIsLocked(false);
75453
- return replaced ? updated : [...prev2, newMessage];
75454
- }
75455
- const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75456
- if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75457
- return prev2;
75458
- }
75459
- return [...prev2, newMessage];
75460
- });
75461
- });
75462
- socket.on("update-bot-message", (updatedData) => {
75463
- console.log("Received bot message update:", updatedData);
75464
- setMessages(
75465
- (prev2) => prev2.map(
75466
- (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75467
- )
75468
- );
75469
- });
75470
- socket.on("error", (error2) => {
75471
- console.error("Socket error:", error2);
75472
- setServerError("Server error occurred");
75473
- });
75474
- socket.onAny((eventName, ...args) => {
75475
- console.log(`Socket event received: ${eventName}`, args);
75476
- });
75477
- const timeoutId = setTimeout(() => {
75478
- if (!serverReadyRef.current) {
75479
- console.log("Server status check failed");
75480
- setServerError("Please check the server");
75490
+ });
75491
+ socket.on("update-bot-message", (updatedData) => {
75492
+ console.log("Received bot message update:", updatedData);
75493
+ setMessages(
75494
+ (prev2) => prev2.map(
75495
+ (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75496
+ )
75497
+ );
75498
+ });
75499
+ socket.on("error", (error2) => {
75500
+ console.error("Socket error:", error2);
75501
+ setServerError("Server error occurred");
75502
+ });
75503
+ socket.onAny((eventName, ...args) => {
75504
+ console.log(`Socket event received: ${eventName}`, args);
75505
+ });
75506
+ const timeoutId = setTimeout(() => {
75507
+ if (!serverReadyRef.current) {
75508
+ console.log("Server status check failed");
75509
+ setServerError(
75510
+ "Server status check failed - please check the server"
75511
+ );
75512
+ setServerStatus("error");
75513
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75514
+ setIsLocked(false);
75515
+ }
75516
+ }, 2e3);
75517
+ return () => {
75518
+ console.log("Disconnecting socket");
75519
+ socket.disconnect();
75520
+ clearTimeout(timeoutId);
75521
+ };
75522
+ } catch (error2) {
75523
+ console.error("Token validation error:", error2);
75524
+ setServerError("Authentication error: Invalid token");
75481
75525
  setServerStatus("error");
75526
+ serverReadyRef.current = false;
75482
75527
  }
75483
- }, 2e3);
75484
- return () => {
75485
- console.log("Disconnecting socket");
75486
- socket.disconnect();
75487
- clearTimeout(timeoutId);
75488
75528
  };
75489
- }, [isSimulated, socketUrl]);
75529
+ validateToken();
75530
+ }, [isSimulated, socketUrl, authToken]);
75490
75531
  React.useEffect(() => {
75491
75532
  if (messageListRef.current) {
75492
75533
  messageListRef.current.scrollTo({
@@ -75505,41 +75546,48 @@ const Chat = ({
75505
75546
  }
75506
75547
  };
75507
75548
  const sendMessage = () => {
75508
- var _a;
75549
+ var _a, _b;
75509
75550
  if (!message2.trim() || isLocked) return;
75551
+ const timestamp = Date.now();
75510
75552
  const userMessage = {
75511
75553
  content: message2,
75512
75554
  sender: handle,
75513
- id: `id_${Date.now()}`,
75514
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
75515
- };
75516
- const thinkingMessage = {
75517
- content: "",
75518
- sender: "bot",
75519
- id: `id_${Date.now()}_thinking`,
75520
- isThinking: true,
75555
+ id: `user_${timestamp}_${Math.random().toString(36).substr(2, 9)}`,
75521
75556
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
75522
75557
  };
75523
75558
  setIsLocked(true);
75524
- setMessages((prev2) => [...prev2, thinkingMessage]);
75525
- if (!((_a = socketRef.current) == null ? void 0 : _a.connected)) {
75559
+ setMessages((prev2) => [...prev2, userMessage]);
75560
+ if ((_a = socketRef.current) == null ? void 0 : _a.connected) {
75561
+ const botMessageId = `bot_${timestamp}`;
75562
+ const thinkingMessage = {
75563
+ content: "",
75564
+ sender: "bot",
75565
+ id: botMessageId,
75566
+ isThinking: true,
75567
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
75568
+ };
75569
+ setMessages((prev2) => [...prev2, thinkingMessage]);
75570
+ }
75571
+ if (!((_b = socketRef.current) == null ? void 0 : _b.connected)) {
75526
75572
  setServerError("Not connected to server");
75527
75573
  setIsLocked(false);
75528
75574
  return;
75529
75575
  }
75530
75576
  socketRef.current.emit("message", userMessage);
75531
- setTimeout(() => {
75532
- setMessages(
75533
- (prev2) => prev2.map(
75534
- (msg) => msg.isThinking ? { ...msg, content: "Processing your message..." } : msg
75535
- )
75536
- );
75537
- }, 300);
75538
- setTimeout(() => {
75539
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75540
- setServerError("No response from server");
75541
- setIsLocked(false);
75542
- }, 1e4);
75577
+ if (socketRef.current.connected) {
75578
+ setTimeout(() => {
75579
+ setMessages(
75580
+ (prev2) => prev2.map(
75581
+ (msg) => msg.isThinking ? { ...msg, content: "Processing your message..." } : msg
75582
+ )
75583
+ );
75584
+ }, 300);
75585
+ setTimeout(() => {
75586
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75587
+ setServerError("No response from server");
75588
+ setIsLocked(false);
75589
+ }, 1e4);
75590
+ }
75543
75591
  setMessage("");
75544
75592
  };
75545
75593
  const toggleChat = () => {
@@ -75548,15 +75596,22 @@ const Chat = ({
75548
75596
  const handleInputChange = (e2) => {
75549
75597
  setMessage(e2.payload.value);
75550
75598
  };
75599
+ if (serverStatus === "error") {
75600
+ return /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { children: "Network error" });
75601
+ }
75602
+ const uniqueMessages = messages2.filter(
75603
+ (msg, index2, self2) => index2 === self2.findIndex((t2) => t2.id === msg.id)
75604
+ );
75605
+ console.log("uniqueMessages", uniqueMessages);
75551
75606
  return /* @__PURE__ */ jsxRuntime.jsxs(ChatContainer, { children: [
75552
75607
  /* @__PURE__ */ jsxRuntime.jsx(HeroContainer, { $isVisible: !isChatOpen, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
75553
- title && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading3", children: title }),
75608
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading3", children: title }) : null,
75554
75609
  /* @__PURE__ */ jsxRuntime.jsx(Subtitle, { children: "Click the Chat Icon below to begin" }),
75555
- serverError && /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { children: serverError })
75610
+ serverError ? /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { children: serverError }) : null
75556
75611
  ] }) }),
75557
75612
  isChatOpen ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
75558
- /* @__PURE__ */ jsxRuntime.jsx(HeroContainer, { $isVisible: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: title && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading2", children: title }) }) }),
75559
- /* @__PURE__ */ jsxRuntime.jsx(MessageList, { ref: messageListRef, children: messages2.map((msg) => /* @__PURE__ */ jsxRuntime.jsx(
75613
+ /* @__PURE__ */ jsxRuntime.jsx(HeroContainer, { $isVisible: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading2", children: title }) : null }) }),
75614
+ /* @__PURE__ */ jsxRuntime.jsx(MessageList, { ref: messageListRef, children: uniqueMessages.map((msg) => /* @__PURE__ */ jsxRuntime.jsx(
75560
75615
  Message$1,
75561
75616
  {
75562
75617
  message: msg.content,
package/dist/index.js CHANGED
@@ -74902,20 +74902,7 @@ const Message$1 = ({ message: message2, handle, isThinking = false }) => {
74902
74902
  const isBot = handle === "bot";
74903
74903
  return /* @__PURE__ */ jsxs(MessageContainer, { $isBot: isBot, children: [
74904
74904
  /* @__PURE__ */ jsx(IconContainer, { children: isBot ? /* @__PURE__ */ jsx(BotIcon, {}) : /* @__PURE__ */ jsx(UserIcon, {}) }),
74905
- /* @__PURE__ */ jsx(TextContainer, { $isBot: isBot, children: isThinking ? /* @__PURE__ */ jsx(ThinkingIndicator, {}) : handle === "bot" ? /* @__PURE__ */ jsx(
74906
- Markdown,
74907
- {
74908
- components: {
74909
- p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "mb-2 last:mb-0", children }),
74910
- ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "list-disc pl-4 mb-2", children }),
74911
- ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "list-decimal pl-4 mb-2", children }),
74912
- li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "mb-1", children }),
74913
- code: ({ children }) => /* @__PURE__ */ jsx("code", { className: "bg-gray-200 rounded px-1 py-0.5", children }),
74914
- pre: ({ children }) => /* @__PURE__ */ jsx("pre", { className: "bg-gray-200 rounded p-2 mb-2 overflow-x-auto", children })
74915
- },
74916
- children: message2
74917
- }
74918
- ) : /* @__PURE__ */ jsx(MessageText, { children: message2 }) })
74905
+ /* @__PURE__ */ jsx(TextContainer, { $isBot: isBot, children: isThinking ? /* @__PURE__ */ jsx(ThinkingIndicator, {}) : handle === "bot" ? /* @__PURE__ */ jsx(Markdown, { children: message2 }) : /* @__PURE__ */ jsx(MessageText, { children: message2 }) })
74919
74906
  ] });
74920
74907
  };
74921
74908
  const getStateColors = (colors2, type4, state) => {
@@ -75331,7 +75318,7 @@ const ChatContainer = styled.div`
75331
75318
  display: flex;
75332
75319
  flex-direction: column;
75333
75320
  position: relative;
75334
- width: 540px;
75321
+ width: 600px;
75335
75322
  overflow: hidden;
75336
75323
  `;
75337
75324
  const HeroContainer = styled.div`
@@ -75381,7 +75368,8 @@ const Chat = ({
75381
75368
  isOpen = false,
75382
75369
  messageHistory = [],
75383
75370
  title = null,
75384
- isSimulated = false
75371
+ isSimulated = false,
75372
+ authToken
75385
75373
  }) => {
75386
75374
  const [isChatOpen, setIsChatOpen] = useState(isOpen);
75387
75375
  const [message2, setMessage] = useState("");
@@ -75395,80 +75383,133 @@ const Chat = ({
75395
75383
  const [isLocked, setIsLocked] = useState(false);
75396
75384
  useEffect(() => {
75397
75385
  if (isSimulated) return;
75398
- console.log("Connecting to socket server at:", socketUrl);
75399
- socketRef.current = lookup(socketUrl, {
75400
- extraHeaders: {
75401
- "Access-Control-Allow-Origin": "*"
75402
- }
75403
- });
75404
- const socket = socketRef.current;
75405
- socket.on("connect", () => {
75406
- console.log("Socket connected successfully");
75407
- });
75408
- socket.on("connect_error", (error2) => {
75409
- console.error("Socket connection error:", error2);
75410
- setServerError("Failed to connect to server");
75411
- setServerStatus("error");
75412
- serverReadyRef.current = false;
75413
- });
75414
- socket.on("new connection", () => {
75415
- console.log("New connection established");
75416
- });
75417
- socket.on("server-ready", () => {
75418
- console.log("Server is ready");
75419
- setServerError("");
75420
- setServerStatus("ready");
75421
- serverReadyRef.current = true;
75422
- });
75423
- socket.on("message", (newMessage) => {
75424
- setMessages((prev2) => {
75425
- if (newMessage.sender === "bot") {
75426
- let replaced = false;
75427
- const updated = prev2.map((msg) => {
75428
- if (msg.isThinking && !replaced) {
75429
- replaced = true;
75430
- return { ...newMessage, isThinking: false };
75386
+ const socketUrlToUse = window.location.hostname === "localhost" && window.location.port === "6006" ? "http://localhost:3000" : socketUrl;
75387
+ console.log("Connecting to socket server at:", socketUrlToUse);
75388
+ const validateToken = async () => {
75389
+ try {
75390
+ const response = await fetch(
75391
+ "https://www.googleapis.com/oauth2/v2/userinfo",
75392
+ {
75393
+ headers: {
75394
+ Authorization: `Bearer ${authToken}`
75431
75395
  }
75432
- return msg;
75396
+ }
75397
+ );
75398
+ if (!response.ok) {
75399
+ throw new Error("Invalid token");
75400
+ }
75401
+ socketRef.current = lookup(socketUrlToUse, {
75402
+ transports: ["polling", "websocket"],
75403
+ reconnection: true,
75404
+ reconnectionAttempts: 5,
75405
+ reconnectionDelay: 1e3,
75406
+ withCredentials: true,
75407
+ forceNew: true,
75408
+ autoConnect: true,
75409
+ timeout: 1e4,
75410
+ auth: {
75411
+ token: authToken,
75412
+ type: "Bearer"
75413
+ }
75414
+ });
75415
+ const socket = socketRef.current;
75416
+ socket.on("connect", () => {
75417
+ console.log("Socket connected successfully");
75418
+ setServerError("");
75419
+ setServerStatus("ready");
75420
+ serverReadyRef.current = true;
75421
+ });
75422
+ socket.on("connect_error", (error2) => {
75423
+ console.error("Socket connection error:", error2);
75424
+ setServerError(`Connection error: ${error2.message}`);
75425
+ setServerStatus("error");
75426
+ serverReadyRef.current = false;
75427
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75428
+ setIsLocked(false);
75429
+ });
75430
+ socket.on("disconnect", (reason) => {
75431
+ console.log("Socket disconnected:", reason);
75432
+ setServerError(`Disconnected: ${reason}`);
75433
+ setServerStatus("error");
75434
+ serverReadyRef.current = false;
75435
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75436
+ setIsLocked(false);
75437
+ });
75438
+ socket.on("new connection", () => {
75439
+ console.log("New connection established");
75440
+ });
75441
+ socket.on("server-ready", () => {
75442
+ console.log("Server is ready");
75443
+ setServerError("");
75444
+ setServerStatus("ready");
75445
+ serverReadyRef.current = true;
75446
+ });
75447
+ socket.on("message", (newMessage) => {
75448
+ setMessages((prev2) => {
75449
+ if (newMessage.sender === "bot") {
75450
+ if (newMessage.content === "Processing your message...") {
75451
+ const hasThinkingMessage = prev2.some((msg) => msg.isThinking);
75452
+ if (hasThinkingMessage) {
75453
+ return prev2;
75454
+ }
75455
+ return [...prev2, { ...newMessage, isThinking: true }];
75456
+ }
75457
+ const thinkingMessage = prev2.find((msg) => msg.isThinking);
75458
+ if (thinkingMessage) {
75459
+ return prev2.map(
75460
+ (msg) => msg.isThinking ? { ...newMessage, isThinking: false } : msg
75461
+ );
75462
+ }
75463
+ return [...prev2, { ...newMessage, isThinking: false }];
75464
+ }
75465
+ const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75466
+ if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75467
+ return prev2;
75468
+ }
75469
+ return [...prev2, newMessage];
75433
75470
  });
75434
75471
  setIsLocked(false);
75435
- return replaced ? updated : [...prev2, newMessage];
75436
- }
75437
- const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75438
- if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75439
- return prev2;
75440
- }
75441
- return [...prev2, newMessage];
75442
- });
75443
- });
75444
- socket.on("update-bot-message", (updatedData) => {
75445
- console.log("Received bot message update:", updatedData);
75446
- setMessages(
75447
- (prev2) => prev2.map(
75448
- (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75449
- )
75450
- );
75451
- });
75452
- socket.on("error", (error2) => {
75453
- console.error("Socket error:", error2);
75454
- setServerError("Server error occurred");
75455
- });
75456
- socket.onAny((eventName, ...args) => {
75457
- console.log(`Socket event received: ${eventName}`, args);
75458
- });
75459
- const timeoutId = setTimeout(() => {
75460
- if (!serverReadyRef.current) {
75461
- console.log("Server status check failed");
75462
- setServerError("Please check the server");
75472
+ });
75473
+ socket.on("update-bot-message", (updatedData) => {
75474
+ console.log("Received bot message update:", updatedData);
75475
+ setMessages(
75476
+ (prev2) => prev2.map(
75477
+ (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75478
+ )
75479
+ );
75480
+ });
75481
+ socket.on("error", (error2) => {
75482
+ console.error("Socket error:", error2);
75483
+ setServerError("Server error occurred");
75484
+ });
75485
+ socket.onAny((eventName, ...args) => {
75486
+ console.log(`Socket event received: ${eventName}`, args);
75487
+ });
75488
+ const timeoutId = setTimeout(() => {
75489
+ if (!serverReadyRef.current) {
75490
+ console.log("Server status check failed");
75491
+ setServerError(
75492
+ "Server status check failed - please check the server"
75493
+ );
75494
+ setServerStatus("error");
75495
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75496
+ setIsLocked(false);
75497
+ }
75498
+ }, 2e3);
75499
+ return () => {
75500
+ console.log("Disconnecting socket");
75501
+ socket.disconnect();
75502
+ clearTimeout(timeoutId);
75503
+ };
75504
+ } catch (error2) {
75505
+ console.error("Token validation error:", error2);
75506
+ setServerError("Authentication error: Invalid token");
75463
75507
  setServerStatus("error");
75508
+ serverReadyRef.current = false;
75464
75509
  }
75465
- }, 2e3);
75466
- return () => {
75467
- console.log("Disconnecting socket");
75468
- socket.disconnect();
75469
- clearTimeout(timeoutId);
75470
75510
  };
75471
- }, [isSimulated, socketUrl]);
75511
+ validateToken();
75512
+ }, [isSimulated, socketUrl, authToken]);
75472
75513
  useEffect(() => {
75473
75514
  if (messageListRef.current) {
75474
75515
  messageListRef.current.scrollTo({
@@ -75487,41 +75528,48 @@ const Chat = ({
75487
75528
  }
75488
75529
  };
75489
75530
  const sendMessage = () => {
75490
- var _a;
75531
+ var _a, _b;
75491
75532
  if (!message2.trim() || isLocked) return;
75533
+ const timestamp = Date.now();
75492
75534
  const userMessage = {
75493
75535
  content: message2,
75494
75536
  sender: handle,
75495
- id: `id_${Date.now()}`,
75496
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
75497
- };
75498
- const thinkingMessage = {
75499
- content: "",
75500
- sender: "bot",
75501
- id: `id_${Date.now()}_thinking`,
75502
- isThinking: true,
75537
+ id: `user_${timestamp}_${Math.random().toString(36).substr(2, 9)}`,
75503
75538
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
75504
75539
  };
75505
75540
  setIsLocked(true);
75506
- setMessages((prev2) => [...prev2, thinkingMessage]);
75507
- if (!((_a = socketRef.current) == null ? void 0 : _a.connected)) {
75541
+ setMessages((prev2) => [...prev2, userMessage]);
75542
+ if ((_a = socketRef.current) == null ? void 0 : _a.connected) {
75543
+ const botMessageId = `bot_${timestamp}`;
75544
+ const thinkingMessage = {
75545
+ content: "",
75546
+ sender: "bot",
75547
+ id: botMessageId,
75548
+ isThinking: true,
75549
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
75550
+ };
75551
+ setMessages((prev2) => [...prev2, thinkingMessage]);
75552
+ }
75553
+ if (!((_b = socketRef.current) == null ? void 0 : _b.connected)) {
75508
75554
  setServerError("Not connected to server");
75509
75555
  setIsLocked(false);
75510
75556
  return;
75511
75557
  }
75512
75558
  socketRef.current.emit("message", userMessage);
75513
- setTimeout(() => {
75514
- setMessages(
75515
- (prev2) => prev2.map(
75516
- (msg) => msg.isThinking ? { ...msg, content: "Processing your message..." } : msg
75517
- )
75518
- );
75519
- }, 300);
75520
- setTimeout(() => {
75521
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75522
- setServerError("No response from server");
75523
- setIsLocked(false);
75524
- }, 1e4);
75559
+ if (socketRef.current.connected) {
75560
+ setTimeout(() => {
75561
+ setMessages(
75562
+ (prev2) => prev2.map(
75563
+ (msg) => msg.isThinking ? { ...msg, content: "Processing your message..." } : msg
75564
+ )
75565
+ );
75566
+ }, 300);
75567
+ setTimeout(() => {
75568
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75569
+ setServerError("No response from server");
75570
+ setIsLocked(false);
75571
+ }, 1e4);
75572
+ }
75525
75573
  setMessage("");
75526
75574
  };
75527
75575
  const toggleChat = () => {
@@ -75530,15 +75578,22 @@ const Chat = ({
75530
75578
  const handleInputChange = (e2) => {
75531
75579
  setMessage(e2.payload.value);
75532
75580
  };
75581
+ if (serverStatus === "error") {
75582
+ return /* @__PURE__ */ jsx(ErrorMessage, { children: "Network error" });
75583
+ }
75584
+ const uniqueMessages = messages2.filter(
75585
+ (msg, index2, self2) => index2 === self2.findIndex((t2) => t2.id === msg.id)
75586
+ );
75587
+ console.log("uniqueMessages", uniqueMessages);
75533
75588
  return /* @__PURE__ */ jsxs(ChatContainer, { children: [
75534
75589
  /* @__PURE__ */ jsx(HeroContainer, { $isVisible: !isChatOpen, children: /* @__PURE__ */ jsxs("div", { children: [
75535
- title && /* @__PURE__ */ jsx(Typography, { variant: "heading3", children: title }),
75590
+ title ? /* @__PURE__ */ jsx(Typography, { variant: "heading3", children: title }) : null,
75536
75591
  /* @__PURE__ */ jsx(Subtitle, { children: "Click the Chat Icon below to begin" }),
75537
- serverError && /* @__PURE__ */ jsx(ErrorMessage, { children: serverError })
75592
+ serverError ? /* @__PURE__ */ jsx(ErrorMessage, { children: serverError }) : null
75538
75593
  ] }) }),
75539
75594
  isChatOpen ? /* @__PURE__ */ jsxs(Fragment, { children: [
75540
- /* @__PURE__ */ jsx(HeroContainer, { $isVisible: true, children: /* @__PURE__ */ jsx("div", { children: title && /* @__PURE__ */ jsx(Typography, { variant: "heading2", children: title }) }) }),
75541
- /* @__PURE__ */ jsx(MessageList, { ref: messageListRef, children: messages2.map((msg) => /* @__PURE__ */ jsx(
75595
+ /* @__PURE__ */ jsx(HeroContainer, { $isVisible: true, children: /* @__PURE__ */ jsx("div", { children: title ? /* @__PURE__ */ jsx(Typography, { variant: "heading2", children: title }) : null }) }),
75596
+ /* @__PURE__ */ jsx(MessageList, { ref: messageListRef, children: uniqueMessages.map((msg) => /* @__PURE__ */ jsx(
75542
75597
  Message$1,
75543
75598
  {
75544
75599
  message: msg.content,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobolt/genesis",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "genesis design system",
5
5
  "author": "gobolt",
6
6
  "license": "MIT",