@robylon/react-native-sdk 2.2.1-staging.1 → 2.2.1

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 (52) hide show
  1. package/README.md +57 -0
  2. package/lib/commonjs/config.js +1 -1
  3. package/lib/commonjs/config.js.map +1 -1
  4. package/lib/commonjs/constants.js +1 -1
  5. package/lib/commonjs/constants.js.map +1 -1
  6. package/lib/module/config.js +1 -1
  7. package/lib/module/config.js.map +1 -1
  8. package/lib/module/constants.js +1 -1
  9. package/lib/module/constants.js.map +1 -1
  10. package/package.json +1 -1
  11. package/robylon-react-native-sdk-2.2.1-staging.1.tgz +0 -0
  12. package/android/src/main/AndroidManifest.xml +0 -3
  13. package/android/src/main/java/com/robylonreactnativesdk/RobylonDownloadModule.java +0 -83
  14. package/android/src/main/java/com/robylonreactnativesdk/RobylonReactNativeSdkPackage.java +0 -24
  15. package/robylon-react-native-sdk-2.2.1-staging.0.tgz +0 -0
  16. package/src/Chatbotsdk.tsx +0 -1191
  17. package/src/FloatingButton/launchers/ImageLauncher.tsx +0 -75
  18. package/src/FloatingButton/launchers/TextLauncher.tsx +0 -84
  19. package/src/FloatingButton/launchers/TextualImageLauncher.tsx +0 -133
  20. package/src/FloatingButton.tsx +0 -97
  21. package/src/LoadingIndicator.tsx +0 -11
  22. package/src/Toast.tsx +0 -65
  23. package/src/components/DebugButton.tsx +0 -46
  24. package/src/components/ErrorBoundary.tsx +0 -38
  25. package/src/config.ts +0 -4
  26. package/src/constants/errorConstants.ts +0 -21
  27. package/src/constants/fontStyles.ts +0 -3
  28. package/src/constants.ts +0 -5
  29. package/src/global.d.ts +0 -11
  30. package/src/hooks/useChatbotEvents.ts +0 -117
  31. package/src/index.tsx +0 -14
  32. package/src/openChatbot.ts +0 -11
  33. package/src/openChatbot.tsx +0 -0
  34. package/src/services/ErrorTrackingService.ts +0 -217
  35. package/src/types/events.ts +0 -28
  36. package/src/types/react-native-flipper-performance-plugin.d.ts +0 -3
  37. package/src/types/react-native-globals.d.ts +0 -10
  38. package/src/utils/animations.ts +0 -120
  39. package/src/utils/colorUtils.ts +0 -35
  40. package/src/utils/cookieUtils.ts +0 -7
  41. package/src/utils/debugConfig.ts +0 -56
  42. package/src/utils/debugMenu.ts +0 -14
  43. package/src/utils/errorHandler.ts +0 -58
  44. package/src/utils/fileDownload.ts +0 -198
  45. package/src/utils/logger.ts +0 -14
  46. package/src/utils/session.ts +0 -26
  47. package/src/utils/systemInfo.ts +0 -110
  48. package/src/utils/webViewStorage.ts +0 -62
  49. package/src/version.ts +0 -2
  50. package/src/versions/version.dev.ts +0 -2
  51. package/src/versions/version.production.ts +0 -2
  52. package/src/versions/version.staging.ts +0 -2
@@ -1,58 +0,0 @@
1
- import { logger } from "./logger";
2
- import { ErrorTypes } from "../constants/errorConstants";
3
- import { Platform } from "react-native";
4
- import { errorTracker } from "../services/ErrorTrackingService";
5
-
6
- // Global error handler for uncaught errors and promise rejections
7
- export const setupGlobalErrorHandlers = () => {
8
- if (__DEV__) {
9
- // Handle synchronous errors
10
- const errorHandler = (error: Error, isFatal?: boolean) => {
11
- errorTracker.trackError(error, "GlobalErrorHandler", {
12
- isFatal,
13
- type: ErrorTypes.RUNTIME_ERROR,
14
- platform: Platform.OS,
15
- });
16
- };
17
-
18
- // Handle promise rejections
19
- const rejectionHandler = (event: any) => {
20
- errorTracker.trackError(
21
- event?.reason || new Error("Unknown Promise Error"),
22
- "UnhandledPromiseRejection",
23
- {
24
- type: ErrorTypes.RUNTIME_ERROR,
25
- platform: Platform.OS,
26
- }
27
- );
28
- };
29
-
30
- // Set up handlers
31
- if ((global as any).ErrorUtils) {
32
- const prevHandler = (global as any).ErrorUtils.getGlobalHandler();
33
- (global as any).ErrorUtils.setGlobalHandler(
34
- (error: Error, isFatal?: boolean) => {
35
- errorHandler(error, isFatal);
36
- prevHandler(error, isFatal);
37
- }
38
- );
39
- }
40
-
41
- // Handle promise rejections
42
- const setupPromiseRejectionTracking = () => {
43
- const tracking = require("promise/setimmediate/rejection-tracking");
44
- tracking.enable({
45
- allRejections: true,
46
- onUnhandled: (id: number, error: Error) => {
47
- rejectionHandler({ reason: error });
48
- },
49
- });
50
- };
51
-
52
- try {
53
- setupPromiseRejectionTracking();
54
- } catch (error) {
55
- logger.warn("Promise rejection tracking setup failed:", error);
56
- }
57
- }
58
- };
@@ -1,198 +0,0 @@
1
- /**
2
- * File: src/utils/fileDownload.ts
3
- * Utility functions for handling file downloads
4
- */
5
-
6
- import { Linking, NativeModules, Platform } from "react-native";
7
- import { logger } from "./logger";
8
-
9
- export interface DownloadRequest {
10
- url: string;
11
- filename?: string;
12
- inPlace?: boolean;
13
- }
14
-
15
- const normalizeUrl = (url: string): string => {
16
- return url?.trim();
17
- };
18
-
19
- const getUrlPathTail = (url?: string): string => {
20
- const cleanedUrl = url?.split("?")?.[0] || "";
21
- return cleanedUrl?.split("/")?.pop()?.trim() || "";
22
- };
23
-
24
- const getExtensionFromName = (name?: string): string => {
25
- if (!name?.includes(".")) return "";
26
- return name.substring(name.lastIndexOf("."));
27
- };
28
-
29
- const resolveDownloadFileName = (filename?: string, url?: string): string => {
30
- const trimmedName = filename?.trim();
31
- if (trimmedName) {
32
- const sanitizedName = trimmedName.replace(/[<>:"/\\|?*\x00-\x1F]/g, "_");
33
- const urlExtension = getExtensionFromName(getUrlPathTail(url));
34
- if (getExtensionFromName(sanitizedName) || !urlExtension)
35
- return sanitizedName;
36
- return `${sanitizedName}${urlExtension}`;
37
- }
38
- const tailName = getUrlPathTail(url);
39
- if (tailName) return tailName.replace(/[<>:"/\\|?*\x00-\x1F]/g, "_");
40
- return `download-robylon-${Date.now()}`;
41
- };
42
-
43
- type RobylonDownloadNativeModule = {
44
- downloadFile: (url: string, filename: string) => Promise<string>;
45
- };
46
-
47
- const isValidHttpUrl = (url: string): boolean => {
48
- return /^https?:\/\//i.test(url);
49
- };
50
-
51
- const getNativeDownloadModule = (): RobylonDownloadNativeModule | null => {
52
- return (
53
- (NativeModules?.RobylonDownloadModule as RobylonDownloadNativeModule) ||
54
- null
55
- );
56
- };
57
-
58
- const openUrlWithFallback = async (url: string): Promise<void> => {
59
- try {
60
- await Linking.openURL(url);
61
- return;
62
- } catch (primaryError) {
63
- logger.warn("Primary URL open failed, trying browser fallback", {
64
- url,
65
- primaryError:
66
- primaryError instanceof Error
67
- ? primaryError?.message
68
- : String(primaryError),
69
- });
70
- }
71
-
72
- await Linking.openURL(
73
- `https://docs.google.com/viewer?url=${encodeURIComponent(url)}`,
74
- );
75
- };
76
-
77
- const downloadOnAndroid = async (
78
- url: string,
79
- filename: string,
80
- ): Promise<void> => {
81
- const module = getNativeDownloadModule();
82
- if (!module?.downloadFile) {
83
- throw new Error("Robylon native download module is not linked on Android");
84
- }
85
- await module.downloadFile(url, filename);
86
- };
87
-
88
- const downloadOniOS = async (url: string, filename: string): Promise<void> => {
89
- const module = getNativeDownloadModule();
90
- if (!module?.downloadFile) {
91
- throw new Error("Robylon native download module is not linked on iOS");
92
- }
93
- await module.downloadFile(url, filename);
94
- };
95
-
96
- const downloadWithNativeStorage = async (
97
- url: string,
98
- filename?: string,
99
- ): Promise<void> => {
100
- const safeName = resolveDownloadFileName(filename, url);
101
- if (Platform.OS === "android") {
102
- await downloadOnAndroid(url, safeName);
103
- return;
104
- }
105
- if (Platform.OS === "ios") {
106
- await downloadOniOS(url, safeName);
107
- return;
108
- }
109
- await openUrlWithFallback(url);
110
- };
111
-
112
- const shouldUseInPlaceDownload = (
113
- downloadRequest?: DownloadRequest,
114
- ): boolean => {
115
- return downloadRequest?.inPlace === true;
116
- };
117
-
118
- /**
119
- * Downloads a file using native storage when possible
120
- * @param url - The URL of the file to download
121
- * @param filename - Optional filename for the download
122
- */
123
- export const downloadFile = async (
124
- url: string,
125
- filename?: string,
126
- inPlace?: boolean,
127
- ): Promise<void> => {
128
- try {
129
- const normalizedUrl = normalizeUrl(url);
130
- logger.debug("Initiating file download", { url: normalizedUrl, filename });
131
-
132
- // Validate URL
133
- if (!normalizedUrl || typeof normalizedUrl !== "string") {
134
- throw new Error("Invalid URL provided for download");
135
- }
136
-
137
- if (!isValidHttpUrl(normalizedUrl)) {
138
- throw new Error("Download URL must be an http/https URL");
139
- }
140
-
141
- if (inPlace) {
142
- try {
143
- await downloadWithNativeStorage(normalizedUrl, filename);
144
- logger.debug("File downloaded with native storage flow");
145
- } catch (nativeDownloadError) {
146
- logger.warn("Native download failed, falling back to URL open", {
147
- url: normalizedUrl,
148
- nativeDownloadError:
149
- nativeDownloadError instanceof Error
150
- ? nativeDownloadError?.message
151
- : String(nativeDownloadError),
152
- });
153
- await openUrlWithFallback(normalizedUrl);
154
- logger.debug("File download opened with fallback browser flow");
155
- }
156
- return;
157
- }
158
-
159
- await openUrlWithFallback(normalizedUrl);
160
- logger.debug("File download opened with legacy URL flow");
161
- } catch (error) {
162
- logger.error("File download failed", {
163
- url,
164
- filename,
165
- error: error instanceof Error ? error?.message : String(error),
166
- });
167
- throw error;
168
- }
169
- };
170
-
171
- /**
172
- * Handles download request from WebView post message
173
- * @param downloadRequest - The download request object
174
- */
175
- export const handleDownloadRequest = async (
176
- downloadRequest: DownloadRequest,
177
- ): Promise<void> => {
178
- const { url, filename } = downloadRequest;
179
-
180
- if (!url) {
181
- logger.error("Download request missing URL");
182
- return;
183
- }
184
-
185
- try {
186
- await downloadFile(
187
- url,
188
- filename,
189
- shouldUseInPlaceDownload(downloadRequest),
190
- );
191
- } catch (error) {
192
- logger.error("Failed to handle download request", {
193
- downloadRequest,
194
- error,
195
- });
196
- // Don't re-throw to avoid breaking the WebView message handling
197
- }
198
- };
@@ -1,14 +0,0 @@
1
- export const logger = {
2
- error: (message: string, error?: any) => {
3
- console.error(message, error);
4
- },
5
- info: (message: string, data?: any) => {
6
- console.info(message, data);
7
- },
8
- warn: (message: string, data?: any) => {
9
- console.warn(message, data);
10
- },
11
- debug: (message: string, data?: any) => {
12
- console.log(message, data);
13
- },
14
- };
@@ -1,26 +0,0 @@
1
- /**
2
- * Session id pass-through between the chatbot web app and the SDK client.
3
- *
4
- * The session id travels on its own message type so that it never reaches
5
- * `onEvent`, `onMessage` or the internal `/users/sdk/record-logs/` endpoint.
6
- * Its only exits from the SDK are the `onSession` prop and `getSessionId()`
7
- * on the ref, both of which the client has to opt into explicitly.
8
- */
9
-
10
- /** Message the web app posts whenever the active session id changes. */
11
- export const SESSION_UPDATED_MESSAGE_TYPE = "SESSION_UPDATED";
12
-
13
- /** Key carrying the resume target inside the `registerUserId` payload. */
14
- export const RESUME_SESSION_KEY = "sessionId";
15
-
16
- /**
17
- * Pulls the session id out of a `SESSION_UPDATED` payload.
18
- *
19
- * Accepts the snake_case, camelCase and nested spellings so a naming slip on
20
- * the web side degrades to a no-op rather than a broken build. Anything that
21
- * is not a non-empty string is dropped.
22
- */
23
- export const extractSessionId = (data: any): string | undefined => {
24
- const raw = data?.session_id ?? data?.sessionId ?? data?.session?.id;
25
- return typeof raw === "string" && raw.length > 0 ? raw : undefined;
26
- };
@@ -1,110 +0,0 @@
1
- import { Platform, Dimensions, PixelRatio } from "react-native";
2
- import { SDK_VERSION } from "../version";
3
-
4
- interface ScreenSize {
5
- width: number;
6
- height: number;
7
- }
8
-
9
- interface SystemInfo {
10
- platform: string;
11
- os: string;
12
- browser: string;
13
- browser_version: string | null;
14
- browser_language: string | null;
15
- sdk_version: string;
16
- device: string;
17
- screen_size: ScreenSize;
18
- }
19
-
20
- // Get device type based on platform and screen dimensions
21
- const getDeviceType = (): string => {
22
- const { width, height } = Dimensions.get("window");
23
- const aspectRatio = height / width;
24
-
25
- if (Platform.OS === "ios") {
26
- return Platform.isPad ? "iPad" : "iPhone";
27
- } else if (Platform.OS === "android") {
28
- return aspectRatio < 1.6 ? "Android Tablet" : "Android Phone";
29
- }
30
- return "Desktop";
31
- };
32
-
33
- // Get screen dimensions with pixel ratio
34
- const getScreenSize = (): ScreenSize => {
35
- return {
36
- width: Math.round(Dimensions.get("window").width * PixelRatio.get()),
37
- height: Math.round(Dimensions.get("window").height * PixelRatio.get()),
38
- };
39
- };
40
-
41
- // Get browser detection script
42
- export const getBrowserAndOSInfoScript = (): string => {
43
- return `
44
- function getOSAndBrowser() {
45
- const userAgent = navigator.userAgent;
46
-
47
- // OS Detection
48
- let os = "unknown";
49
- if (userAgent.indexOf("Win") !== -1) os = "Windows";
50
- else if (userAgent.indexOf("Mac") !== -1) os = "MacOS";
51
- else if (userAgent.indexOf("Linux") !== -1) os = "Linux";
52
- else if (userAgent.indexOf("Android") !== -1) os = "Android";
53
- else if (userAgent.indexOf("like Mac") !== -1) os = "iOS";
54
-
55
- // Browser Detection
56
- let browser = "unknown";
57
- let browserVersion = null;
58
- if (userAgent.indexOf("Chrome") !== -1) {
59
- browser = "Chrome";
60
- const chromeMatch = userAgent.match(/Chrome\\/([0-9.]+)/);
61
- browserVersion = chromeMatch ? chromeMatch[1] : null;
62
- } else if (userAgent.indexOf("Safari") !== -1) {
63
- browser = "Safari";
64
- const safariMatch = userAgent.match(/Version\\/([0-9.]+)/);
65
- browserVersion = safariMatch ? safariMatch[1] : null;
66
- } else if (userAgent.indexOf("Firefox") !== -1) {
67
- browser = "Firefox";
68
- const firefoxMatch = userAgent.match(/Firefox\\/([0-9.]+)/);
69
- browserVersion = firefoxMatch ? firefoxMatch[1] : null;
70
- } else if (userAgent.indexOf("Edge") !== -1) {
71
- browser = "Edge";
72
- const edgeMatch = userAgent.match(/Edge\\/([0-9.]+)/);
73
- browserVersion = edgeMatch ? edgeMatch[1] : null;
74
- } else if (userAgent.indexOf("MSIE") !== -1 || userAgent.indexOf("Trident/") !== -1) {
75
- browser = "IE";
76
- const ieMatch = userAgent.match(/(?:MSIE |rv:)([0-9.]+)/);
77
- browserVersion = ieMatch ? ieMatch[1] : null;
78
- }
79
-
80
- // Browser Language
81
- const browserLanguage = navigator.language || navigator.languages?.[0] || null;
82
-
83
- window.ReactNativeWebView.postMessage(JSON.stringify({
84
- type: 'SYSTEM_INFO',
85
- data: { os, browser, browser_version: browserVersion, browser_language: browserLanguage }
86
- }));
87
- }
88
- getOSAndBrowser();
89
- true;
90
- `;
91
- };
92
-
93
- // Get complete system information
94
- export const getSystemInfo = (webViewSystemInfo: {
95
- os: string;
96
- browser: string;
97
- browser_version?: string | null;
98
- browser_language?: string | null;
99
- }): SystemInfo => {
100
- return {
101
- platform: Platform.OS,
102
- os: webViewSystemInfo.os || Platform.OS,
103
- browser: webViewSystemInfo.browser || "WebView",
104
- browser_version: webViewSystemInfo.browser_version || null,
105
- browser_language: webViewSystemInfo.browser_language || null,
106
- sdk_version: SDK_VERSION,
107
- device: getDeviceType(),
108
- screen_size: getScreenSize(),
109
- };
110
- };
@@ -1,62 +0,0 @@
1
- import { logger } from "./logger";
2
-
3
- export enum StorageMessageType {
4
- GET_STORAGE = "GET_STORAGE",
5
- SET_STORAGE = "SET_STORAGE",
6
- STORAGE_READY = "STORAGE_READY",
7
- STORAGE_ERROR = "STORAGE_ERROR",
8
- STORAGE_RESPONSE = "STORAGE_RESPONSE",
9
- }
10
-
11
- export interface StorageMessage {
12
- type: StorageMessageType;
13
- key?: string;
14
- value?: string;
15
- error?: string;
16
- }
17
-
18
- export const getStorageScript = () => `
19
- window.handleStorageOperation = function(message) {
20
- try {
21
- switch(message.type) {
22
- case '${StorageMessageType.GET_STORAGE}':
23
- const value = localStorage.getItem(message.key);
24
- window.ReactNativeWebView.postMessage(JSON.stringify({
25
- type: '${StorageMessageType.STORAGE_RESPONSE}',
26
- key: message.key,
27
- value: value
28
- }));
29
- break;
30
- case '${StorageMessageType.SET_STORAGE}':
31
- localStorage.setItem(message.key, message.value);
32
- window.ReactNativeWebView.postMessage(JSON.stringify({
33
- type: '${StorageMessageType.STORAGE_RESPONSE}',
34
- key: message.key,
35
- value: message.value
36
- }));
37
- break;
38
- }
39
- } catch (error) {
40
- window.ReactNativeWebView.postMessage(JSON.stringify({
41
- type: '${StorageMessageType.STORAGE_ERROR}',
42
- error: error.message
43
- }));
44
- }
45
- };
46
-
47
- window.ReactNativeWebView.postMessage(JSON.stringify({
48
- type: '${StorageMessageType.STORAGE_READY}'
49
- }));
50
- `;
51
-
52
- export const createStorageMessage = (
53
- type: StorageMessageType,
54
- key?: string,
55
- value?: string
56
- ): string => {
57
- return `window.handleStorageOperation(${JSON.stringify({
58
- type,
59
- key,
60
- value,
61
- })});`;
62
- };
package/src/version.ts DELETED
@@ -1,2 +0,0 @@
1
- // This file is auto-generated. Do not modify it manually.
2
- export { SDK_VERSION } from './versions/version.staging';
@@ -1,2 +0,0 @@
1
- // This file is auto-generated. Do not modify it manually.
2
- export const SDK_VERSION = '2.0.22-dev.0';
@@ -1,2 +0,0 @@
1
- // This file is auto-generated. Do not modify it manually.
2
- export const SDK_VERSION = "0.0.0";
@@ -1,2 +0,0 @@
1
- // This file is auto-generated. Do not modify it manually.
2
- export const SDK_VERSION = '2.2.1-staging.1';