@robylon/web-react-sdk 1.1.28-staging.2 → 1.1.28-staging.21

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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/index.js +556 -17
  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/index.d.ts +3 -1
  9. package/dist/cjs/types/index.react.d.ts +1 -0
  10. package/dist/cjs/types/index.vanilla.d.ts +3 -2
  11. package/dist/cjs/types/react/components/Chatbot.d.ts +1 -0
  12. package/dist/cjs/types/react/components/ChatbotFloatingButton.d.ts +12 -0
  13. package/dist/cjs/types/react/components/ChatbotIframe.d.ts +12 -0
  14. package/dist/cjs/types/react/components/ErrorBoundary.d.ts +6 -5
  15. package/dist/cjs/types/react/hooks/useChatbotEvents.d.ts +16 -0
  16. package/dist/cjs/types/react/hooks/useChatbotState.d.ts +17 -0
  17. package/dist/cjs/types/vanilla/index.d.ts +3 -1
  18. package/dist/esm/index.js +556 -18
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/legacy.js +1 -1
  21. package/dist/esm/legacy.js.map +1 -1
  22. package/dist/esm/react.js +1 -1
  23. package/dist/esm/react.js.map +1 -1
  24. package/dist/esm/types/index.d.ts +3 -1
  25. package/dist/esm/types/index.react.d.ts +1 -0
  26. package/dist/esm/types/index.vanilla.d.ts +3 -2
  27. package/dist/esm/types/react/components/Chatbot.d.ts +1 -0
  28. package/dist/esm/types/react/components/ChatbotFloatingButton.d.ts +12 -0
  29. package/dist/esm/types/react/components/ChatbotIframe.d.ts +12 -0
  30. package/dist/esm/types/react/components/ErrorBoundary.d.ts +6 -5
  31. package/dist/esm/types/react/hooks/useChatbotEvents.d.ts +16 -0
  32. package/dist/esm/types/react/hooks/useChatbotState.d.ts +17 -0
  33. package/dist/esm/types/vanilla/index.d.ts +3 -1
  34. package/dist/index.d.ts +36 -2
  35. package/dist/legacy.d.ts +162 -0
  36. package/dist/react.d.ts +45 -0
  37. package/dist/umd/robylon.js +557 -21
  38. package/dist/umd/robylon.js.map +1 -1
  39. package/dist/umd/robylon.min.js +1 -1
  40. package/dist/umd/robylon.min.js.map +1 -1
  41. package/dist/umd/types/index.d.ts +3 -1
  42. package/dist/umd/types/index.react.d.ts +1 -0
  43. package/dist/umd/types/index.vanilla.d.ts +3 -2
  44. package/dist/umd/types/react/components/Chatbot.d.ts +1 -0
  45. package/dist/umd/types/react/components/ChatbotFloatingButton.d.ts +12 -0
  46. package/dist/umd/types/react/components/ChatbotIframe.d.ts +12 -0
  47. package/dist/umd/types/react/components/ErrorBoundary.d.ts +6 -5
  48. package/dist/umd/types/react/hooks/useChatbotEvents.d.ts +16 -0
  49. package/dist/umd/types/react/hooks/useChatbotState.d.ts +17 -0
  50. package/dist/umd/types/vanilla/index.d.ts +3 -1
  51. package/package.json +8 -4
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/sdk/1.1.28-staging.1/robylon.min.js"></script>
16
+ <script src="https://staging-cdn.robylon.com/1.1.28-staging.20/robylon.min.js"></script>
17
17
  ```
18
18
 
19
19
  Or via npm:
package/dist/cjs/index.js CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var react = require('react');
7
+
5
8
  /******************************************************************************
6
9
  Copyright (c) Microsoft Corporation.
7
10
 
@@ -716,11 +719,22 @@ var ChatbotEmbed = /** @class */ (function () {
716
719
  /**
717
720
  * Environment configuration for the SDK
718
721
  */
719
- // Default configuration values
722
+ // Get current environment from build-time
723
+ var NODE_ENV = "staging" ;
724
+ // Default configuration values based on environment
720
725
  var DEFAULT_CONFIG = {
721
- copilotUrl: "https://app.robylon.ai",
722
- environment: "production",
723
- apiUrl: "https://api.robylon.ai",
726
+ // Default URLs for each environment
727
+ copilotUrl: {
728
+ development: "https://dev.robylon.ai",
729
+ staging: "https://staging.d2s3wsqyyond1h.amplifyapp.com",
730
+ production: "https://app.robylon.ai",
731
+ },
732
+ environment: NODE_ENV,
733
+ apiUrl: {
734
+ development: "https://dev-api.robylon.ai",
735
+ staging: "https://stage-api.robylon.ai",
736
+ production: "https://api.robylon.ai",
737
+ },
724
738
  };
725
739
  // Store custom config values
726
740
  var customConfig = {};
@@ -734,10 +748,21 @@ var setEnvironmentConfig = function (config) {
734
748
  * Gets environment configuration with defaults
735
749
  */
736
750
  var getEnvironmentConfig = function () {
751
+ // Determine current environment
752
+ var environment = customConfig.environment || NODE_ENV;
753
+ // Ensure we pick URLs appropriate for the current environment
754
+ var envType = environment === "staging"
755
+ ? "staging"
756
+ : environment === "development"
757
+ ? "development"
758
+ : "production";
759
+ // Get default values for current environment
760
+ var defaultCopilotUrl = DEFAULT_CONFIG.copilotUrl[envType];
761
+ var defaultApiUrl = DEFAULT_CONFIG.apiUrl[envType];
737
762
  return {
738
- copilotUrl: customConfig.copilotUrl || DEFAULT_CONFIG.copilotUrl,
739
- environment: customConfig.environment || DEFAULT_CONFIG.environment,
740
- apiUrl: customConfig.apiUrl || DEFAULT_CONFIG.apiUrl,
763
+ copilotUrl: customConfig.copilotUrl || defaultCopilotUrl,
764
+ environment: environment,
765
+ apiUrl: customConfig.apiUrl || defaultApiUrl,
741
766
  };
742
767
  };
743
768
 
@@ -1011,18 +1036,38 @@ var getSystemInfo = function () {
1011
1036
  };
1012
1037
 
1013
1038
  /**
1014
- * Initialize the Robylon SDK with custom environment settings
1039
+ * Initialize the SDK with custom environment settings
1040
+ * @internal This is primarily for internal use and advanced debugging.
1041
+ * Normal users should not need to call this function.
1015
1042
  */
1016
1043
  function init(config) {
1017
- // Make sure apiUrl is properly set when using init
1018
- var configWithDefaults = __assign(__assign({}, config), { apiUrl: config.apiUrl ||
1019
- (config.environment === "staging"
1020
- ? "https://stage-api.robylon.ai"
1021
- : config.environment === "development"
1022
- ? "https://dev-api.robylon.ai"
1023
- : "https://api.robylon.ai") });
1024
- setEnvironmentConfig(configWithDefaults);
1025
- logger.log("Robylon SDK environment initialized with custom config", configWithDefaults);
1044
+ // For internal SDK initialization - not intended for general user use
1045
+ // We prioritize built-in environment settings based on NODE_ENV
1046
+ // Get current environment from build-time
1047
+ var currentEnv = "staging" ;
1048
+ // Default environment-specific API URLs
1049
+ var defaultApiUrls = {
1050
+ development: "https://dev-api.robylon.ai",
1051
+ staging: "https://stage-api.robylon.ai",
1052
+ production: "https://api.robylon.ai",
1053
+ };
1054
+ // Default environment-specific Copilot URLs
1055
+ var defaultCopilotUrls = {
1056
+ development: "https://dev.robylon.ai",
1057
+ staging: "https://staging.d2s3wsqyyond1h.amplifyapp.com",
1058
+ production: "https://app.robylon.ai",
1059
+ };
1060
+ // Only override with user values in non-production environments or if explicitly allowed
1061
+ var isProduction = currentEnv === "production";
1062
+ config.allowProductionOverride === "true" && isProduction;
1063
+ {
1064
+ // Use environment-specific defaults as fallbacks
1065
+ var configWithDefaults = __assign(__assign({}, config), { apiUrl: config.apiUrl ||
1066
+ defaultApiUrls[currentEnv], copilotUrl: config.copilotUrl ||
1067
+ defaultCopilotUrls[currentEnv], environment: config.environment || currentEnv });
1068
+ setEnvironmentConfig(configWithDefaults);
1069
+ logger.log("Robylon SDK environment initialized with custom config", configWithDefaults);
1070
+ }
1026
1071
  }
1027
1072
  /**
1028
1073
  * Create a new Robylon chatbot instance
@@ -1116,6 +1161,499 @@ function create(config) {
1116
1161
  });
1117
1162
  }
1118
1163
 
1164
+ /**
1165
+ * Error Boundary component to catch and handle React rendering errors
1166
+ */
1167
+ var ErrorBoundary = /** @class */ (function (_super) {
1168
+ __extends(ErrorBoundary, _super);
1169
+ function ErrorBoundary(props) {
1170
+ var _this = _super.call(this, props) || this;
1171
+ _this.state = {
1172
+ hasError: false,
1173
+ error: null,
1174
+ };
1175
+ return _this;
1176
+ }
1177
+ ErrorBoundary.getDerivedStateFromError = function (error) {
1178
+ return {
1179
+ hasError: true,
1180
+ error: error,
1181
+ };
1182
+ };
1183
+ ErrorBoundary.prototype.componentDidCatch = function (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
+ });
1190
+ };
1191
+ ErrorBoundary.prototype.render = function () {
1192
+ if (this.state.hasError) {
1193
+ // You can render any custom fallback UI
1194
+ return null; // Silently fail to not disrupt the user experience
1195
+ }
1196
+ return this.props.children;
1197
+ };
1198
+ return ErrorBoundary;
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);
1567
+
1568
+ /**
1569
+ * Main Chatbot component that renders the chatbot UI
1570
+ */
1571
+ var RobylonChatbot = react.memo(function (_a) {
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;
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) {
1582
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent(event);
1583
+ }, [onEvent]);
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,
1595
+ }
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) {
1642
+ return null;
1643
+ }
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 }));
1645
+ }, function (prevProps, nextProps) {
1646
+ return (prevProps.api_key === nextProps.api_key &&
1647
+ prevProps.user_id === nextProps.user_id &&
1648
+ prevProps.user_token === nextProps.user_token &&
1649
+ JSON.stringify(prevProps.user_profile) ===
1650
+ JSON.stringify(nextProps.user_profile));
1651
+ });
1652
+ /**
1653
+ * Wrapped Chatbot component with error boundary
1654
+ */
1655
+ var ChatbotWithErrorBoundary = function (props) { return (jsxRuntime.jsx(ErrorBoundary, { componentName: "RobylonChatbot", children: jsxRuntime.jsx(RobylonChatbot, __assign({}, props)) })); };
1656
+
1119
1657
  // Expose the public API
1120
1658
  var Robylon = {
1121
1659
  /**
@@ -1147,6 +1685,7 @@ if (typeof window !== "undefined") {
1147
1685
  window.Robylon = Robylon;
1148
1686
  }
1149
1687
 
1688
+ exports.Chatbot = ChatbotWithErrorBoundary;
1150
1689
  exports.create = create;
1151
1690
  exports.default = Robylon;
1152
1691
  exports.init = init;