@getecho-ai/react-native-sdk 1.0.0

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.
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ /**
3
+ * WebViewBridge - Handles communication between WebView and React Native
4
+ *
5
+ * Uses postMessage API for bidirectional communication:
6
+ * - WebView → Native: window.ReactNativeWebView.postMessage()
7
+ * - Native → WebView: webViewRef.injectJavaScript()
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.WebViewBridge = exports.webViewBridge = void 0;
14
+ const CallbackManager_1 = __importDefault(require("./CallbackManager"));
15
+ class WebViewBridge {
16
+ constructor() {
17
+ this.messageHandlers = new Set();
18
+ this.webViewRef = null;
19
+ }
20
+ /**
21
+ * Set the WebView reference for sending messages to WebView
22
+ */
23
+ setWebViewRef(ref) {
24
+ this.webViewRef = ref;
25
+ }
26
+ /**
27
+ * Register a message handler
28
+ */
29
+ onMessage(handler) {
30
+ this.messageHandlers.add(handler);
31
+ // Return unsubscribe function
32
+ return () => {
33
+ this.messageHandlers.delete(handler);
34
+ };
35
+ }
36
+ /**
37
+ * Handle incoming message from WebView
38
+ * This is called by the WebView's onMessage prop
39
+ */
40
+ handleMessage(event) {
41
+ try {
42
+ const data = JSON.parse(event.nativeEvent.data);
43
+ console.log("[EchoSDK] Received from WebView:", data);
44
+ const message = {
45
+ type: data.type,
46
+ callbackId: data.callbackId,
47
+ payload: data.payload ?? data,
48
+ };
49
+ // First, handle internal messages
50
+ this.handleInternalMessage(message);
51
+ // Then, notify all registered handlers
52
+ for (const handler of this.messageHandlers) {
53
+ try {
54
+ handler(message);
55
+ }
56
+ catch (error) {
57
+ console.error("[EchoSDK] Message handler error:", error);
58
+ }
59
+ }
60
+ }
61
+ catch (error) {
62
+ console.error("[EchoSDK] Failed to parse WebView message:", error);
63
+ }
64
+ }
65
+ /**
66
+ * Send message to WebView
67
+ */
68
+ sendToWebView(type, payload, callbackId) {
69
+ if (!this.webViewRef) {
70
+ console.warn("[EchoSDK] WebView ref not set, cannot send message");
71
+ return;
72
+ }
73
+ const message = {
74
+ type,
75
+ callbackId,
76
+ payload,
77
+ };
78
+ const jsCode = `
79
+ (function() {
80
+ window.dispatchEvent(new MessageEvent('message', {
81
+ data: ${JSON.stringify(message)}
82
+ }));
83
+ })();
84
+ true;
85
+ `;
86
+ this.webViewRef.injectJavaScript(jsCode);
87
+ console.log("[EchoSDK] Sent to WebView:", message);
88
+ }
89
+ /**
90
+ * Send a raw message to WebView without wrapping payload
91
+ * Used when the web embed expects root-level fields.
92
+ */
93
+ sendRawToWebView(message) {
94
+ console.log("[EchoSDK] Sending raw to WebView:", message);
95
+ if (!this.webViewRef) {
96
+ console.warn("[EchoSDK] WebView ref not set, cannot send message");
97
+ return;
98
+ }
99
+ const serialized = JSON.stringify(message);
100
+ const serializedString = JSON.stringify(serialized);
101
+ const jsCode = `
102
+ (function() {
103
+ const payload = JSON.parse(${serializedString});
104
+ window.dispatchEvent(new MessageEvent('message', { data: payload }));
105
+ })();
106
+ true;
107
+ `;
108
+ this.webViewRef.injectJavaScript(jsCode);
109
+ console.log("[EchoSDK] Sent raw to WebView:", message);
110
+ }
111
+ /**
112
+ * Initialize WebView with config
113
+ */
114
+ initWebView(config) {
115
+ this.sendToWebView("init", config);
116
+ }
117
+ /**
118
+ * Complete an action in WebView
119
+ */
120
+ completeActionInWebView(callbackId, result) {
121
+ this.sendToWebView("actionComplete", result, callbackId);
122
+ }
123
+ /**
124
+ * Handle internal messages (action completion, etc.)
125
+ */
126
+ handleInternalMessage(message) {
127
+ switch (message.type) {
128
+ case "actionComplete":
129
+ if (message.callbackId) {
130
+ CallbackManager_1.default.completeAction(message.callbackId, message.payload);
131
+ }
132
+ break;
133
+ case "chatReady":
134
+ console.log("[EchoSDK] WebView chat is ready");
135
+ break;
136
+ default:
137
+ // Other message types are handled by registered handlers
138
+ break;
139
+ }
140
+ }
141
+ /**
142
+ * Clear all handlers (useful on unmount)
143
+ */
144
+ clearHandlers() {
145
+ this.messageHandlers.clear();
146
+ }
147
+ }
148
+ exports.WebViewBridge = WebViewBridge;
149
+ // Export singleton instance
150
+ exports.webViewBridge = new WebViewBridge();
151
+ exports.default = exports.webViewBridge;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * EchoChat - Combined chat component
3
+ *
4
+ * Includes both the floating button and the chat modal.
5
+ * This is the simplest way to add Echo chat to a partner app.
6
+ *
7
+ * Usage:
8
+ * ```jsx
9
+ * <EchoProvider config={config}>
10
+ * <EchoChat floating position="bottom-right" />
11
+ * </EchoProvider>
12
+ * ```
13
+ */
14
+ import type React from "react";
15
+ type EchoChatProps = {
16
+ floating?: boolean;
17
+ position?: "bottom-right" | "bottom-left";
18
+ };
19
+ export declare const EchoChat: React.FC<EchoChatProps>;
20
+ export default EchoChat;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * EchoChat - Combined chat component
4
+ *
5
+ * Includes both the floating button and the chat modal.
6
+ * This is the simplest way to add Echo chat to a partner app.
7
+ *
8
+ * Usage:
9
+ * ```jsx
10
+ * <EchoProvider config={config}>
11
+ * <EchoChat floating position="bottom-right" />
12
+ * </EchoProvider>
13
+ * ```
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.EchoChat = void 0;
20
+ const react_1 = require("react");
21
+ const react_native_1 = require("react-native");
22
+ const EchoChatButton_1 = __importDefault(require("./EchoChatButton"));
23
+ const EchoChatModal_1 = __importDefault(require("./EchoChatModal"));
24
+ const EchoChat = ({ floating = true, position = "bottom-right", }) => {
25
+ const [isVisible, setIsVisible] = (0, react_1.useState)(false);
26
+ const openChat = () => setIsVisible(true);
27
+ const closeChat = () => setIsVisible(false);
28
+ return (<react_native_1.View style={floating ? styles.container : undefined}>
29
+ {floating && <EchoChatButton_1.default onPress={openChat} position={position}/>}
30
+
31
+ <EchoChatModal_1.default onClose={closeChat} visible={isVisible}/>
32
+ </react_native_1.View>);
33
+ };
34
+ exports.EchoChat = EchoChat;
35
+ const styles = react_native_1.StyleSheet.create({
36
+ container: {
37
+ position: "absolute",
38
+ top: 0,
39
+ left: 0,
40
+ right: 0,
41
+ bottom: 0,
42
+ pointerEvents: "box-none",
43
+ },
44
+ });
45
+ exports.default = exports.EchoChat;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * EchoChatButton - Floating chat button
3
+ *
4
+ * Displays a floating button that opens the chat modal when pressed.
5
+ * Can show an unread message badge.
6
+ */
7
+ import type React from "react";
8
+ type EchoChatButtonProps = {
9
+ onPress: () => void;
10
+ unreadCount?: number;
11
+ position?: "bottom-right" | "bottom-left";
12
+ color?: string;
13
+ };
14
+ export declare const EchoChatButton: React.FC<EchoChatButtonProps>;
15
+ export default EchoChatButton;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * EchoChatButton - Floating chat button
4
+ *
5
+ * Displays a floating button that opens the chat modal when pressed.
6
+ * Can show an unread message badge.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.EchoChatButton = void 0;
10
+ const react_native_1 = require("react-native");
11
+ const EchoChatButton = ({ onPress, unreadCount = 0, position = "bottom-right", color = "#007AFF", }) => {
12
+ const positionStyle = position === "bottom-right" ? styles.right : styles.left;
13
+ return (<react_native_1.TouchableOpacity activeOpacity={0.8} onPress={onPress} style={[styles.button, positionStyle, { backgroundColor: color }]}>
14
+ <react_native_1.Text style={styles.icon}>💬</react_native_1.Text>
15
+ {unreadCount > 0 && (<react_native_1.View style={styles.badge}>
16
+ <react_native_1.Text style={styles.badgeText}>
17
+ {unreadCount > 99 ? "99+" : unreadCount}
18
+ </react_native_1.Text>
19
+ </react_native_1.View>)}
20
+ </react_native_1.TouchableOpacity>);
21
+ };
22
+ exports.EchoChatButton = EchoChatButton;
23
+ const styles = react_native_1.StyleSheet.create({
24
+ button: {
25
+ position: "absolute",
26
+ bottom: 20,
27
+ width: 56,
28
+ height: 56,
29
+ borderRadius: 28,
30
+ justifyContent: "center",
31
+ alignItems: "center",
32
+ shadowColor: "#000",
33
+ shadowOffset: { width: 0, height: 2 },
34
+ shadowOpacity: 0.25,
35
+ shadowRadius: 4,
36
+ elevation: 5,
37
+ },
38
+ right: {
39
+ right: 20,
40
+ },
41
+ left: {
42
+ left: 20,
43
+ },
44
+ icon: {
45
+ fontSize: 24,
46
+ },
47
+ badge: {
48
+ position: "absolute",
49
+ top: -4,
50
+ right: -4,
51
+ backgroundColor: "#FF3B30",
52
+ borderRadius: 12,
53
+ minWidth: 24,
54
+ height: 24,
55
+ justifyContent: "center",
56
+ alignItems: "center",
57
+ paddingHorizontal: 6,
58
+ },
59
+ badgeText: {
60
+ color: "#fff",
61
+ fontSize: 12,
62
+ fontWeight: "bold",
63
+ },
64
+ });
65
+ exports.default = exports.EchoChatButton;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * EchoChatModal - Chat interface using WebView
3
+ *
4
+ * Embeds Echo web chat via WebView with postMessage bridge
5
+ * Handles all communication between WebView and React Native
6
+ */
7
+ import type React from "react";
8
+ type EchoChatModalProps = {
9
+ visible: boolean;
10
+ onClose: () => void;
11
+ };
12
+ export declare const EchoChatModal: React.FC<EchoChatModalProps>;
13
+ export default EchoChatModal;