@robylon/web-react-sdk 1.1.28-staging.14 → 1.1.28-staging.15

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.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/index.js +453 -117
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/legacy.js +1 -1
  5. package/dist/cjs/legacy.js.map +1 -1
  6. package/dist/cjs/react.js +1 -1
  7. package/dist/cjs/react.js.map +1 -1
  8. package/dist/cjs/types/react/components/ChatbotFloatingButton.d.ts +12 -0
  9. package/dist/cjs/types/react/components/ChatbotIframe.d.ts +12 -0
  10. package/dist/cjs/types/react/components/ErrorBoundary.d.ts +6 -5
  11. package/dist/cjs/types/react/hooks/useChatbotEvents.d.ts +16 -0
  12. package/dist/cjs/types/react/hooks/useChatbotState.d.ts +17 -0
  13. package/dist/esm/index.js +451 -115
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/legacy.js +1 -1
  16. package/dist/esm/legacy.js.map +1 -1
  17. package/dist/esm/react.js +1 -1
  18. package/dist/esm/react.js.map +1 -1
  19. package/dist/esm/types/react/components/ChatbotFloatingButton.d.ts +12 -0
  20. package/dist/esm/types/react/components/ChatbotIframe.d.ts +12 -0
  21. package/dist/esm/types/react/components/ErrorBoundary.d.ts +6 -5
  22. package/dist/esm/types/react/hooks/useChatbotEvents.d.ts +16 -0
  23. package/dist/esm/types/react/hooks/useChatbotState.d.ts +17 -0
  24. package/dist/umd/robylon.js +453 -117
  25. package/dist/umd/robylon.js.map +1 -1
  26. package/dist/umd/robylon.min.js +1 -1
  27. package/dist/umd/robylon.min.js.map +1 -1
  28. package/dist/umd/types/react/components/ChatbotFloatingButton.d.ts +12 -0
  29. package/dist/umd/types/react/components/ChatbotIframe.d.ts +12 -0
  30. package/dist/umd/types/react/components/ErrorBoundary.d.ts +6 -5
  31. package/dist/umd/types/react/hooks/useChatbotEvents.d.ts +16 -0
  32. package/dist/umd/types/react/hooks/useChatbotState.d.ts +17 -0
  33. package/package.json +1 -1
package/README.md CHANGED
@@ -13,7 +13,7 @@ npm install @robylon/web-react-sdk
13
13
  ### Vanilla JavaScript
14
14
 
15
15
  ```html
16
- <script src="https://staging-cdn.robylon.com/1.1.28-staging.13/robylon.min.js"></script>
16
+ <script src="https://staging-cdn.robylon.com/1.1.28-staging.14/robylon.min.js"></script>
17
17
  ```
18
18
 
19
19
  Or via npm:
package/dist/cjs/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var React = require('react');
6
+ var react = require('react');
7
7
 
8
8
  /******************************************************************************
9
9
  Copyright (c) Microsoft Corporation.
@@ -1166,147 +1166,483 @@ function create(config) {
1166
1166
  */
1167
1167
  var ErrorBoundary = /** @class */ (function (_super) {
1168
1168
  __extends(ErrorBoundary, _super);
1169
- function ErrorBoundary() {
1170
- var _this = _super !== null && _super.apply(this, arguments) || this;
1169
+ function ErrorBoundary(props) {
1170
+ var _this = _super.call(this, props) || this;
1171
1171
  _this.state = {
1172
1172
  hasError: false,
1173
+ error: null,
1173
1174
  };
1174
1175
  return _this;
1175
1176
  }
1176
- ErrorBoundary.getDerivedStateFromError = function (_) {
1177
- return { hasError: true };
1177
+ ErrorBoundary.getDerivedStateFromError = function (error) {
1178
+ return {
1179
+ hasError: true,
1180
+ error: error,
1181
+ };
1178
1182
  };
1179
1183
  ErrorBoundary.prototype.componentDidCatch = function (error, errorInfo) {
1180
- // Log the error
1181
- logger.error("Error in ".concat(this.props.componentName || "unknown", " component:"), error, errorInfo);
1184
+ var componentName = this.props.componentName;
1185
+ logger.error("[Robylon Error] Error in ".concat(componentName, " component:"), error, errorInfo);
1186
+ // You could also log to an error reporting service here
1187
+ console.error({
1188
+ componentStack: errorInfo.componentStack,
1189
+ });
1182
1190
  };
1183
1191
  ErrorBoundary.prototype.render = function () {
1184
1192
  if (this.state.hasError) {
1185
- return null;
1193
+ // You can render any custom fallback UI
1194
+ return null; // Silently fail to not disrupt the user experience
1186
1195
  }
1187
1196
  return this.props.children;
1188
1197
  };
1189
1198
  return ErrorBoundary;
1190
- }(React.Component));
1199
+ }(react.Component));
1200
+
1201
+ var ChatbotEventType;
1202
+ (function (ChatbotEventType) {
1203
+ ChatbotEventType["CHATBOT_BUTTON_LOADED"] = "CHATBOT_BUTTON_LOADED";
1204
+ ChatbotEventType["CHATBOT_BUTTON_CLICKED"] = "CHATBOT_BUTTON_CLICKED";
1205
+ ChatbotEventType["CHATBOT_OPENED"] = "CHATBOT_OPENED";
1206
+ ChatbotEventType["CHATBOT_CLOSED"] = "CHATBOT_CLOSED";
1207
+ ChatbotEventType["CHATBOT_APP_READY"] = "CHATBOT_APP_READY";
1208
+ ChatbotEventType["CHATBOT_LOADED"] = "CHATBOT_LOADED";
1209
+ ChatbotEventType["CHAT_INITIALIZED"] = "CHAT_INITIALIZED";
1210
+ ChatbotEventType["SESSION_REFRESHED"] = "SESSION_REFRESHED";
1211
+ ChatbotEventType["CHAT_INITIALIZATION_FAILED"] = "CHAT_INITIALIZATION_FAILED";
1212
+ })(ChatbotEventType || (ChatbotEventType = {}));
1213
+ var InternalEventType;
1214
+ (function (InternalEventType) {
1215
+ InternalEventType["CHAT_MOVED"] = "CHAT_MOVED";
1216
+ InternalEventType["CHATBOT_TOKEN_EXHAUSTED"] = "CHATBOT_TOKEN_EXHAUSTED";
1217
+ })(InternalEventType || (InternalEventType = {}));
1218
+
1219
+ function useChatbotState(props) {
1220
+ var _this = this;
1221
+ var api_key = props.api_key, user_id = props.user_id, user_token = props.user_token, user_profile = props.user_profile;
1222
+ var _a = react.useState(false), isInitializing = _a[0], setIsInitializing = _a[1];
1223
+ var _b = react.useState(false), isInitialized = _b[0], setIsInitialized = _b[1];
1224
+ var _c = react.useState(null), error = _c[0], setError = _c[1];
1225
+ var _d = react.useState(null), chatbotConfig = _d[0], setChatbotConfig = _d[1];
1226
+ var _e = react.useState(false), isIframeVisible = _e[0], setIsIframeVisible = _e[1];
1227
+ // Initialize the chatbot
1228
+ react.useEffect(function () {
1229
+ var initChatbot = function () { return __awaiter(_this, void 0, void 0, function () {
1230
+ var userId, isAnonymous, apiResponse, systemInfo, finalUserProfile, config, err_1, errorMessage;
1231
+ var _a, _b, _c, _d, _e, _f, _g;
1232
+ return __generator(this, function (_h) {
1233
+ switch (_h.label) {
1234
+ case 0:
1235
+ if (!api_key) {
1236
+ setError("API key is required");
1237
+ return [2 /*return*/];
1238
+ }
1239
+ if (isInitializing || isInitialized)
1240
+ return [2 /*return*/];
1241
+ setIsInitializing(true);
1242
+ _h.label = 1;
1243
+ case 1:
1244
+ _h.trys.push([1, 3, 4, 5]);
1245
+ userId = user_id;
1246
+ isAnonymous = false;
1247
+ // Handle anonymous users
1248
+ if (!userId) {
1249
+ userId = getCookie("rblyn_anon") || generateUUID();
1250
+ setCookie("rblyn_anon", String(userId), 365);
1251
+ isAnonymous = true;
1252
+ }
1253
+ return [4 /*yield*/, fetchChatbotConfig(api_key, userId, user_token)];
1254
+ case 2:
1255
+ apiResponse = _h.sent();
1256
+ systemInfo = getSystemInfo();
1257
+ finalUserProfile = __assign(__assign({}, systemInfo), user_profile);
1258
+ config = {
1259
+ chatbotId: api_key,
1260
+ userId: userId ? String(userId) : null,
1261
+ token: user_token,
1262
+ isAnonymous: isAnonymous,
1263
+ domain: getEnvironmentConfig().copilotUrl,
1264
+ brand_colour: ((_b = (_a = apiResponse.user.org_info.brand_config) === null || _a === void 0 ? void 0 : _a.colors) === null || _b === void 0 ? void 0 : _b.brand_color) ||
1265
+ "#6a26cd",
1266
+ image_url: ((_d = (_c = apiResponse.user.org_info) === null || _c === void 0 ? void 0 : _c.brand_config) === null || _d === void 0 ? void 0 : _d.launcher_logo_url) || "",
1267
+ userProfile: finalUserProfile,
1268
+ chat_interface_config: {
1269
+ chat_bubble_prompts: [],
1270
+ display_name: ((_e = apiResponse.user.org_info.brand_config) === null || _e === void 0 ? void 0 : _e.display_name) || "",
1271
+ welcome_message: ((_f = apiResponse.user.org_info.brand_config) === null || _f === void 0 ? void 0 : _f.welcome_message) ||
1272
+ "Hey! What can we help you with today?",
1273
+ redirect_url: ((_g = apiResponse.user.org_info.brand_config) === null || _g === void 0 ? void 0 : _g.redirect_url) || "",
1274
+ },
1275
+ };
1276
+ // Store the config
1277
+ setChatbotConfig(config);
1278
+ setIsInitialized(true);
1279
+ return [3 /*break*/, 5];
1280
+ case 3:
1281
+ err_1 = _h.sent();
1282
+ errorMessage = err_1 instanceof Error ? err_1.message : "Failed to initialize chatbot";
1283
+ setError(errorMessage);
1284
+ logger.error("Chatbot initialization failed:", err_1);
1285
+ return [3 /*break*/, 5];
1286
+ case 4:
1287
+ setIsInitializing(false);
1288
+ return [7 /*endfinally*/];
1289
+ case 5: return [2 /*return*/];
1290
+ }
1291
+ });
1292
+ }); };
1293
+ initChatbot();
1294
+ }, [api_key, user_id, user_token, user_profile]);
1295
+ var toggleIframeVisibility = function () {
1296
+ setIsIframeVisible(function (prev) { return !prev; });
1297
+ };
1298
+ var closeIframe = function () {
1299
+ setIsIframeVisible(false);
1300
+ };
1301
+ return {
1302
+ isInitialized: isInitialized,
1303
+ isInitializing: isInitializing,
1304
+ error: error,
1305
+ chatbotConfig: chatbotConfig,
1306
+ isIframeVisible: isIframeVisible,
1307
+ toggleIframeVisibility: toggleIframeVisibility,
1308
+ closeIframe: closeIframe,
1309
+ };
1310
+ }
1311
+
1312
+ function useChatbotEvents(props) {
1313
+ var onEvent = props.onEvent;
1314
+ var emitEvent = react.useCallback(function (type, data) {
1315
+ var event = {
1316
+ type: type,
1317
+ timestamp: Date.now(),
1318
+ data: data,
1319
+ };
1320
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent(event);
1321
+ }, [onEvent]);
1322
+ var onInternalEvent = react.useCallback(function (eventType, additionalData) {
1323
+ // Handle internal events if needed
1324
+ // This can be expanded based on requirements
1325
+ }, []);
1326
+ return {
1327
+ emitEvent: emitEvent,
1328
+ onInternalEvent: onInternalEvent,
1329
+ };
1330
+ }
1331
+
1332
+ var ChatbotFloatingButton = function (_a) {
1333
+ var config = _a.config, toggleIframe = _a.toggleIframe, isIframeVisible = _a.isIframeVisible, onEvent = _a.onEvent, onInternalEvent = _a.onInternalEvent;
1334
+ // If config is null, don't render anything
1335
+ if (!config)
1336
+ return null;
1337
+ var buttonRef = react.useRef(null);
1338
+ var copilotUrl = getEnvironmentConfig().copilotUrl;
1339
+ react.useEffect(function () {
1340
+ if (buttonRef.current) {
1341
+ requestAnimationFrame(function () {
1342
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({
1343
+ type: ChatbotEventType.CHATBOT_BUTTON_LOADED,
1344
+ timestamp: Date.now(),
1345
+ });
1346
+ onInternalEvent(ChatbotEventType.CHATBOT_BUTTON_LOADED);
1347
+ });
1348
+ }
1349
+ }, [onEvent, onInternalEvent]);
1350
+ var renderIcon = function () {
1351
+ if (isIframeVisible) {
1352
+ return (jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("g", { id: "Chevron_Down", children: jsxRuntime.jsx("path", { id: "Vector", d: "M19 9L12 16L5 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }));
1353
+ }
1354
+ return (jsxRuntime.jsx("img", { src: config.image_url || "".concat(copilotUrl, "/chatbubble.png"), alt: "Chat", style: {
1355
+ zIndex: 1000,
1356
+ cursor: "pointer",
1357
+ borderRadius: "50%",
1358
+ objectFit: "cover",
1359
+ width: "100%",
1360
+ height: "100%",
1361
+ } }));
1362
+ };
1363
+ logger.log("config chatbotfloatingbutton", config);
1364
+ return (jsxRuntime.jsx("div", { ref: buttonRef, className: "message-bubble-container", style: {
1365
+ position: "fixed",
1366
+ bottom: "1.5rem",
1367
+ right: "1.5rem",
1368
+ zIndex: 1000,
1369
+ width: "48px",
1370
+ height: "48px",
1371
+ display: "flex",
1372
+ flexDirection: "column-reverse",
1373
+ backgroundColor: config.brand_colour,
1374
+ color: getBestFontColor(config.brand_colour),
1375
+ borderRadius: "50%",
1376
+ alignItems: "center",
1377
+ justifyContent: "center",
1378
+ cursor: "pointer",
1379
+ overflow: "hidden",
1380
+ }, onClick: toggleIframe, children: renderIcon() }));
1381
+ };
1382
+ var ChatbotFloatingButton$1 = react.memo(ChatbotFloatingButton);
1383
+
1384
+ var ChatbotIframe = function (_a) {
1385
+ var config = _a.config, isVisible = _a.isVisible, onClose = _a.onClose, onEvent = _a.onEvent, onInternalEvent = _a.onInternalEvent;
1386
+ // If config is null, don't render anything
1387
+ if (!config)
1388
+ return null;
1389
+ var iframeRef = react.useRef(null);
1390
+ var isInitializedRef = react.useRef(false);
1391
+ var hasRegisteredRef = react.useRef(false);
1392
+ // Add responsive styles handler
1393
+ var applyResponsiveStyles = react.useCallback(function () {
1394
+ var iframe = iframeRef.current;
1395
+ if (!iframe)
1396
+ return;
1397
+ if ((window === null || window === void 0 ? void 0 : window.innerWidth) < 560) {
1398
+ // Mobile styles
1399
+ iframe.style.width = "100vw";
1400
+ iframe.style.minWidth = "300px";
1401
+ iframe.style.right = "0";
1402
+ iframe.style.bottom = "0";
1403
+ iframe.style.height = "100vh";
1404
+ iframe.style.flexDirection = "column";
1405
+ iframe.style.flexGrow = "1";
1406
+ iframe.style.borderRadius = "0";
1407
+ iframe.style.top = "0";
1408
+ iframe.style.maxHeight = "100%";
1409
+ }
1410
+ else {
1411
+ // Desktop styles
1412
+ iframe.style.width = "26%";
1413
+ iframe.style.minWidth = "400px";
1414
+ iframe.style.right = "32px";
1415
+ iframe.style.bottom = "86px";
1416
+ iframe.style.height = "calc(100vh - 3rem - 10vh)";
1417
+ iframe.style.borderRadius = "1rem";
1418
+ iframe.style.top = "calc(10vh - 32px)";
1419
+ iframe.style.maxHeight = "45rem";
1420
+ }
1421
+ }, []);
1422
+ // Add resize listener
1423
+ react.useEffect(function () {
1424
+ window === null || window === void 0 ? void 0 : window.addEventListener("resize", applyResponsiveStyles);
1425
+ applyResponsiveStyles(); // Apply initial styles
1426
+ return function () { return window === null || window === void 0 ? void 0 : window.removeEventListener("resize", applyResponsiveStyles); };
1427
+ }, [applyResponsiveStyles]);
1428
+ // Initialize iframe only once
1429
+ react.useEffect(function () {
1430
+ var iframe = iframeRef.current;
1431
+ if (!iframe || isInitializedRef.current)
1432
+ return;
1433
+ var copilotUrl = getEnvironmentConfig().copilotUrl;
1434
+ iframe.src = "".concat(copilotUrl, "/chatbot-plugin?id=").concat(config.chatbotId);
1435
+ isInitializedRef.current = true;
1436
+ var handleIframeLoad = function () {
1437
+ var _a, _b;
1438
+ var targetOrigin = new URL(iframe.src).origin || copilotUrl;
1439
+ (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
1440
+ domain: (_b = window === null || window === void 0 ? void 0 : window.location) === null || _b === void 0 ? void 0 : _b.hostname,
1441
+ name: "checkDomain",
1442
+ }, targetOrigin);
1443
+ };
1444
+ iframe.addEventListener("load", handleIframeLoad);
1445
+ return function () { return iframe.removeEventListener("load", handleIframeLoad); };
1446
+ }, [config.chatbotId]);
1447
+ // Handle visibility changes in separate effect
1448
+ react.useEffect(function () {
1449
+ var _a, _b, _c, _d;
1450
+ var iframe = iframeRef.current;
1451
+ if (!iframe || !isInitializedRef.current)
1452
+ return;
1453
+ var copilotUrl = getEnvironmentConfig().copilotUrl;
1454
+ iframe.style.display = isVisible ? "block" : "none";
1455
+ if (iframe.contentWindow && isVisible) {
1456
+ var targetOrigin = new URL(iframe.src).origin || copilotUrl;
1457
+ (_a = iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
1458
+ domain: (_b = window === null || window === void 0 ? void 0 : window.location) === null || _b === void 0 ? void 0 : _b.hostname,
1459
+ name: "openFrame",
1460
+ }, targetOrigin);
1461
+ if (!(hasRegisteredRef === null || hasRegisteredRef === void 0 ? void 0 : hasRegisteredRef.current)) {
1462
+ (_c = iframe.contentWindow) === null || _c === void 0 ? void 0 : _c.postMessage({
1463
+ domain: (_d = window === null || window === void 0 ? void 0 : window.location) === null || _d === void 0 ? void 0 : _d.hostname,
1464
+ action: "registerUserId",
1465
+ data: {
1466
+ userId: config === null || config === void 0 ? void 0 : config.userId,
1467
+ token: config === null || config === void 0 ? void 0 : config.token,
1468
+ userProfile: config === null || config === void 0 ? void 0 : config.userProfile,
1469
+ isAnonymous: config === null || config === void 0 ? void 0 : config.isAnonymous,
1470
+ },
1471
+ }, targetOrigin);
1472
+ hasRegisteredRef.current = true;
1473
+ }
1474
+ }
1475
+ }, [isVisible, config.userId, config.token, config.userProfile]);
1476
+ react.useEffect(function () {
1477
+ var iframe = iframeRef.current;
1478
+ if (!iframe || !isInitializedRef.current)
1479
+ return;
1480
+ var copilotUrl = getEnvironmentConfig().copilotUrl;
1481
+ if (isVisible) {
1482
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({
1483
+ type: ChatbotEventType.CHATBOT_OPENED,
1484
+ timestamp: Date.now(),
1485
+ });
1486
+ onInternalEvent(ChatbotEventType.CHATBOT_OPENED);
1487
+ }
1488
+ // Handle messages from iframe
1489
+ var handleMessage = function (event) {
1490
+ var _a, _b, _c, _d, _e, _f, _g;
1491
+ if (event.origin === copilotUrl) {
1492
+ // Handle existing messages
1493
+ if (event.data === "closeChatbot") {
1494
+ onClose();
1495
+ return;
1496
+ }
1497
+ if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === "CHATBOT_TOKEN_EXHAUSTED") {
1498
+ onInternalEvent(InternalEventType.CHATBOT_TOKEN_EXHAUSTED);
1499
+ return;
1500
+ }
1501
+ // Handle CHATBOT_LOADED message
1502
+ if (((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === "CHATBOT_LOADED") {
1503
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({
1504
+ type: ChatbotEventType.CHATBOT_LOADED,
1505
+ timestamp: Date.now(),
1506
+ });
1507
+ onInternalEvent(ChatbotEventType.CHATBOT_LOADED);
1508
+ }
1509
+ if (((_c = event.data) === null || _c === void 0 ? void 0 : _c.type) === "CHAT_INITIALIZED") {
1510
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({
1511
+ type: ChatbotEventType.CHAT_INITIALIZED,
1512
+ timestamp: Date.now(),
1513
+ });
1514
+ onInternalEvent(ChatbotEventType.CHAT_INITIALIZED);
1515
+ }
1516
+ if (((_d = event.data) === null || _d === void 0 ? void 0 : _d.type) === "CHAT_INITIALIZATION_FAILED") {
1517
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({
1518
+ type: ChatbotEventType.CHAT_INITIALIZATION_FAILED,
1519
+ timestamp: Date.now(),
1520
+ });
1521
+ onInternalEvent(ChatbotEventType.CHAT_INITIALIZATION_FAILED, {
1522
+ error: (_e = event.data) === null || _e === void 0 ? void 0 : _e.error,
1523
+ });
1524
+ }
1525
+ if (((_f = event.data) === null || _f === void 0 ? void 0 : _f.type) === "SESSION_REFRESHED") {
1526
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({
1527
+ type: ChatbotEventType.SESSION_REFRESHED,
1528
+ timestamp: Date.now(),
1529
+ });
1530
+ onInternalEvent(ChatbotEventType.SESSION_REFRESHED);
1531
+ }
1532
+ if (((_g = event.data) === null || _g === void 0 ? void 0 : _g.type) === "CHAT_MOVED") {
1533
+ onInternalEvent(InternalEventType.CHAT_MOVED, {
1534
+ from: event.data.from,
1535
+ to: event.data.to,
1536
+ trigger: event.data.trigger,
1537
+ });
1538
+ }
1539
+ }
1540
+ };
1541
+ window === null || window === void 0 ? void 0 : window.addEventListener("message", handleMessage);
1542
+ return function () { return window === null || window === void 0 ? void 0 : window.removeEventListener("message", handleMessage); };
1543
+ }, [onClose, onEvent, onInternalEvent, config.chatbotId, isVisible]);
1544
+ // Update iframe when user profile changes
1545
+ react.useEffect(function () {
1546
+ var _a;
1547
+ if (!iframeRef.current || !config || !isVisible)
1548
+ return;
1549
+ var iframe = iframeRef.current;
1550
+ var domain = getEnvironmentConfig().copilotUrl;
1551
+ (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
1552
+ action: "updateUserProfile",
1553
+ user_profile: config.userProfile,
1554
+ }, domain);
1555
+ }, [config.userProfile, isVisible]);
1556
+ return (jsxRuntime.jsx("iframe", { ref: iframeRef, id: "chat-iframe-rbyln", style: {
1557
+ position: "fixed",
1558
+ zIndex: 20000000,
1559
+ border: "none",
1560
+ boxShadow: "0px 0px 40px 0px rgba(14, 14, 15, 0.24)",
1561
+ transformOrigin: "bottom right",
1562
+ transition: "transform 0.3s ease-out",
1563
+ display: isVisible ? "block" : "none",
1564
+ } }));
1565
+ };
1566
+ var ChatbotIframe$1 = react.memo(ChatbotIframe);
1191
1567
 
1192
1568
  /**
1193
1569
  * Main Chatbot component that renders the chatbot UI
1194
1570
  */
1195
- var RobylonChatbot = React.memo(function (_a) {
1571
+ var RobylonChatbot = react.memo(function (_a) {
1196
1572
  var api_key = _a.api_key, user_id = _a.user_id, user_token = _a.user_token, user_profile = _a.user_profile, onEvent = _a.onEvent;
1197
- // Reference to the ChatbotEmbed instance
1198
- var chatbotRef = React.useRef(null);
1199
- // Track initialization state
1200
- var _b = React.useState(false), isInitializing = _b[0], setIsInitializing = _b[1];
1201
- var _c = React.useState(false), isInitialized = _c[0], setIsInitialized = _c[1];
1202
- var _d = React.useState(null), error = _d[0], setError = _d[1];
1203
- var _e = React.useState(null), chatbotConfig = _e[0], setChatbotConfig = _e[1];
1204
- // Stabilize onEvent callback
1205
- var stableOnEvent = React.useCallback(function (event) {
1573
+ react.useEffect(function () {
1574
+ });
1575
+ var stateProps = react.useMemo(function () { return ({
1576
+ api_key: api_key,
1577
+ user_id: user_id,
1578
+ user_token: user_token,
1579
+ user_profile: user_profile,
1580
+ }); }, [api_key, user_id, user_token, user_profile]);
1581
+ var stableOnEvent = react.useCallback(function (event) {
1206
1582
  onEvent === null || onEvent === void 0 ? void 0 : onEvent(event);
1207
1583
  }, [onEvent]);
1208
- // Initialize the chatbot
1209
- var initializeChatbot = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
1210
- var userId, isAnonymous, apiResponse, systemInfo, finalUserProfile, config, err_1, errorMessage;
1211
- var _a, _b, _c, _d, _e, _f, _g;
1212
- return __generator(this, function (_h) {
1213
- switch (_h.label) {
1214
- case 0:
1215
- if (!api_key) {
1216
- setError("API key is required");
1217
- return [2 /*return*/];
1218
- }
1219
- if (isInitializing || isInitialized)
1220
- return [2 /*return*/];
1221
- setIsInitializing(true);
1222
- _h.label = 1;
1223
- case 1:
1224
- _h.trys.push([1, 3, 4, 5]);
1225
- userId = user_id;
1226
- isAnonymous = false;
1227
- // Handle anonymous users
1228
- if (!userId) {
1229
- userId = getCookie("rblyn_anon") || generateUUID();
1230
- setCookie("rblyn_anon", String(userId), 365);
1231
- isAnonymous = true;
1232
- }
1233
- return [4 /*yield*/, fetchChatbotConfig(api_key, userId, user_token)];
1234
- case 2:
1235
- apiResponse = _h.sent();
1236
- systemInfo = getSystemInfo();
1237
- finalUserProfile = __assign(__assign({}, systemInfo), user_profile);
1238
- config = {
1239
- chatbotId: api_key,
1240
- userId: userId ? String(userId) : null,
1241
- token: user_token,
1242
- isAnonymous: isAnonymous,
1243
- domain: getEnvironmentConfig().copilotUrl,
1244
- brand_colour: ((_b = (_a = apiResponse.user.org_info.brand_config) === null || _a === void 0 ? void 0 : _a.colors) === null || _b === void 0 ? void 0 : _b.brand_color) ||
1245
- "#6a26cd",
1246
- image_url: ((_d = (_c = apiResponse.user.org_info) === null || _c === void 0 ? void 0 : _c.brand_config) === null || _d === void 0 ? void 0 : _d.launcher_logo_url) || "",
1247
- userProfile: finalUserProfile,
1248
- chat_interface_config: {
1249
- chat_bubble_prompts: [],
1250
- display_name: ((_e = apiResponse.user.org_info.brand_config) === null || _e === void 0 ? void 0 : _e.display_name) || "",
1251
- welcome_message: ((_f = apiResponse.user.org_info.brand_config) === null || _f === void 0 ? void 0 : _f.welcome_message) ||
1252
- "Hey! What can we help you with today?",
1253
- redirect_url: ((_g = apiResponse.user.org_info.brand_config) === null || _g === void 0 ? void 0 : _g.redirect_url) || "",
1254
- },
1255
- };
1256
- // Store the config
1257
- setChatbotConfig(config);
1258
- // Create the ChatbotEmbed instance
1259
- chatbotRef.current = new ChatbotEmbed(config);
1260
- // Register event handler
1261
- if (stableOnEvent) {
1262
- chatbotRef.current.on("*", stableOnEvent);
1263
- }
1264
- setIsInitialized(true);
1265
- return [3 /*break*/, 5];
1266
- case 3:
1267
- err_1 = _h.sent();
1268
- errorMessage = err_1 instanceof Error ? err_1.message : "Failed to initialize chatbot";
1269
- setError(errorMessage);
1270
- logger.error("Chatbot initialization failed:", err_1);
1271
- return [3 /*break*/, 5];
1272
- case 4:
1273
- setIsInitializing(false);
1274
- return [7 /*endfinally*/];
1275
- case 5: return [2 /*return*/];
1276
- }
1277
- });
1278
- }); }, [api_key, user_id, user_token, stableOnEvent]);
1279
- // Initialize on component mount
1280
- React.useEffect(function () {
1281
- if (api_key) {
1282
- initializeChatbot();
1283
- }
1284
- // Cleanup on unmount
1285
- return function () {
1286
- if (chatbotRef.current) {
1287
- chatbotRef.current.destroy();
1288
- chatbotRef.current = null;
1584
+ var _b = useChatbotState(stateProps), isInitialized = _b.isInitialized, error = _b.error, chatbotConfig = _b.chatbotConfig, isIframeVisible = _b.isIframeVisible, toggleIframeVisibility = _b.toggleIframeVisibility, closeIframe = _b.closeIframe;
1585
+ var eventProps = react.useMemo(function () { return ({
1586
+ api_key: api_key,
1587
+ user_profile: stateProps.user_profile,
1588
+ onEvent: stableOnEvent,
1589
+ chatbotConfig: chatbotConfig
1590
+ ? {
1591
+ isAnonymous: chatbotConfig.isAnonymous,
1592
+ userId: chatbotConfig.userId
1593
+ ? String(chatbotConfig.userId)
1594
+ : null,
1289
1595
  }
1290
- };
1291
- }, [initializeChatbot]);
1292
- // Update chatbot when user profile changes
1293
- React.useEffect(function () {
1294
- if (chatbotRef.current && isInitialized && chatbotConfig) {
1295
- var systemInfo = getSystemInfo();
1296
- chatbotRef.current.updateConfig({
1297
- userProfile: __assign(__assign({}, systemInfo), user_profile),
1298
- });
1299
- }
1300
- }, [user_profile, isInitialized]);
1301
- // Don't render anything if there are errors or not initialized
1302
- if (!api_key || error || !isInitialized) {
1596
+ : null,
1597
+ }); }, [
1598
+ api_key,
1599
+ stateProps.user_profile,
1600
+ stableOnEvent,
1601
+ chatbotConfig === null || chatbotConfig === void 0 ? void 0 : chatbotConfig.isAnonymous,
1602
+ chatbotConfig === null || chatbotConfig === void 0 ? void 0 : chatbotConfig.userId,
1603
+ ]);
1604
+ var _c = useChatbotEvents(__assign({}, eventProps)), emitEvent = _c.emitEvent, onInternalEvent = _c.onInternalEvent;
1605
+ var handleClose = react.useCallback(function () {
1606
+ closeIframe();
1607
+ emitEvent(ChatbotEventType.CHATBOT_CLOSED);
1608
+ }, [closeIframe, emitEvent]);
1609
+ var handleButtonClick = react.useCallback(function () {
1610
+ toggleIframeVisibility();
1611
+ emitEvent(isIframeVisible
1612
+ ? ChatbotEventType.CHATBOT_CLOSED
1613
+ : ChatbotEventType.CHATBOT_BUTTON_CLICKED);
1614
+ }, [toggleIframeVisibility, emitEvent, isIframeVisible]);
1615
+ var floatingButtonProps = react.useMemo(function () { return ({
1616
+ config: chatbotConfig,
1617
+ toggleIframe: handleButtonClick,
1618
+ isIframeVisible: isIframeVisible,
1619
+ onEvent: stableOnEvent,
1620
+ onInternalEvent: onInternalEvent,
1621
+ }); }, [
1622
+ chatbotConfig,
1623
+ handleButtonClick,
1624
+ isIframeVisible,
1625
+ stableOnEvent,
1626
+ onInternalEvent,
1627
+ ]);
1628
+ var iframeProps = react.useMemo(function () { return ({
1629
+ config: chatbotConfig,
1630
+ isVisible: isIframeVisible,
1631
+ onClose: handleClose,
1632
+ onEvent: stableOnEvent,
1633
+ onInternalEvent: onInternalEvent,
1634
+ }); }, [
1635
+ chatbotConfig,
1636
+ isIframeVisible,
1637
+ handleClose,
1638
+ stableOnEvent,
1639
+ onInternalEvent,
1640
+ ]);
1641
+ if (!api_key || error || !chatbotConfig) {
1303
1642
  return null;
1304
1643
  }
1305
- // The ChatbotEmbed handles all rendering via DOM manipulation,
1306
- // so we don't need to return any visible elements here
1307
- return null;
1644
+ return (jsxRuntime.jsx(ErrorBoundary, { componentName: "RobylonChatbot", children: isInitialized ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ErrorBoundary, { componentName: "ChatbotFloatingButton", children: jsxRuntime.jsx(ChatbotFloatingButton$1, __assign({}, floatingButtonProps)) }), jsxRuntime.jsx(ErrorBoundary, { componentName: "ChatbotIframe", children: jsxRuntime.jsx(ChatbotIframe$1, __assign({}, iframeProps)) })] })) : null }));
1308
1645
  }, function (prevProps, nextProps) {
1309
- // Memoization comparison
1310
1646
  return (prevProps.api_key === nextProps.api_key &&
1311
1647
  prevProps.user_id === nextProps.user_id &&
1312
1648
  prevProps.user_token === nextProps.user_token &&