react-native-newinstance-chat 0.1.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,239 @@
1
+ import Foundation
2
+ import LiveAndAiChat
3
+ import React
4
+ import UIKit
5
+
6
+ /// Anything that can route an event payload through to the JS bridge.
7
+ /// The Obj-C `NewinstanceChat` class adopts this in a class extension
8
+ /// (see NewinstanceChat.mm) — Swift only needs the protocol so it
9
+ /// doesn't have to import the auto-generated `NewinstanceChat-Swift.h`
10
+ /// (which would create a circular header dependency at build time).
11
+ @objc public protocol NewinstanceChatEmitter: AnyObject {
12
+ @objc func emitEvent(_ name: String, body: Any?)
13
+ }
14
+
15
+ /// Swift implementation backing the `NewinstanceChat` TurboModule.
16
+ ///
17
+ /// Holds a single `LiveAndAiChat` SDK instance constructed lazily on
18
+ /// `configure(...)`. Repeated `configure(...)` calls tear down and
19
+ /// rebuild — hosts almost never want concurrent chat sessions.
20
+ ///
21
+ /// Events are pushed to JS via the Obj-C bridge class's `emitEvent:body:`
22
+ /// (which uses RCTDeviceEventEmitter under the hood). The emitter
23
+ /// reference is set by `NewinstanceChat` at init.
24
+ @objc(NewinstanceChatImpl)
25
+ public final class NewinstanceChatImpl: NSObject, LiveAndAiChatDelegate {
26
+
27
+ @objc public weak var emitter: NewinstanceChatEmitter?
28
+
29
+ private var sdk: LiveAndAiChat?
30
+ private var pendingUser: ChatUser?
31
+
32
+ // MARK: - configure / setUser / initialize
33
+
34
+ @objc(configure:resolver:rejecter:)
35
+ public func configure(_ configDict: NSDictionary,
36
+ resolver: @escaping RCTPromiseResolveBlock,
37
+ rejecter: @escaping RCTPromiseRejectBlock) {
38
+ guard let apiKey = configDict["apiKey"] as? String, !apiKey.isEmpty else {
39
+ rejecter("E_CONFIG", "apiKey is required", nil)
40
+ return
41
+ }
42
+ let baseUrl = configDict["baseUrl"] as? String
43
+ let initialMessage = configDict["initialMessage"] as? String
44
+ let transport: TransportMode? = {
45
+ switch configDict["transport"] as? String {
46
+ case "sse": return .sse
47
+ case "ws": return .ws
48
+ default: return nil
49
+ }
50
+ }()
51
+
52
+ DispatchQueue.main.async { [weak self] in
53
+ guard let self = self else { return }
54
+ do {
55
+ let cfg = try LiveAndAiChatConfig(
56
+ apiKey: apiKey,
57
+ baseUrl: baseUrl ?? LiveAndAiChatConfig.defaultBaseUrl,
58
+ transport: transport,
59
+ initialMessage: initialMessage
60
+ )
61
+ let builder = LiveAndAiChat.Builder().config(cfg)
62
+ if let user = self.pendingUser { _ = builder.user(user) }
63
+ self.sdk?.destroy()
64
+ let instance = try builder.build()
65
+ instance.addDelegate(self)
66
+ self.sdk = instance
67
+ self.pendingUser = nil
68
+ resolver(nil)
69
+ } catch let e as LiveAndAiChatError {
70
+ rejecter("E_BUILD", e.message, e)
71
+ } catch {
72
+ rejecter("E_BUILD", error.localizedDescription, error)
73
+ }
74
+ }
75
+ }
76
+
77
+ @objc(setUser:)
78
+ public func setUser(_ userDict: NSDictionary) {
79
+ guard let name = userDict["customerName"] as? String, !name.isEmpty else { return }
80
+ let user = ChatUser(
81
+ customerName: name,
82
+ customerId: userDict["customerId"] as? String,
83
+ customerEmail: userDict["customerEmail"] as? String
84
+ )
85
+ DispatchQueue.main.async { [weak self] in
86
+ guard let self = self else { return }
87
+ if let sdk = self.sdk {
88
+ sdk.setUser(user)
89
+ } else {
90
+ self.pendingUser = user
91
+ }
92
+ }
93
+ }
94
+
95
+ @objc(initializeWithResolver:rejecter:)
96
+ public func initialize(resolver: @escaping RCTPromiseResolveBlock,
97
+ rejecter: @escaping RCTPromiseRejectBlock) {
98
+ guard let sdk = sdk else {
99
+ rejecter("E_NOT_CONFIGURED", "configure() must be called before initialize()", nil)
100
+ return
101
+ }
102
+ DispatchQueue.main.async {
103
+ sdk.initialize()
104
+ resolver(nil)
105
+ }
106
+ }
107
+
108
+ // MARK: - Native chat presentation
109
+
110
+ @objc public func openChat() {
111
+ DispatchQueue.main.async { [weak self] in
112
+ guard let self = self, let sdk = self.sdk else { return }
113
+ guard let host = self.topPresentedViewController() else { return }
114
+ // `present(from:)` mounts the SDK's native chat screen modally and
115
+ // calls `openChat()` itself once presented. Calling the SDK's bare
116
+ // `openChat()` only flips internal state — it shows no UI.
117
+ sdk.present(from: host)
118
+ }
119
+ }
120
+
121
+ @objc public func closeChat() {
122
+ DispatchQueue.main.async { [weak self] in self?.sdk?.closeChat() }
123
+ }
124
+
125
+ // MARK: - Programmatic actions
126
+
127
+ @objc public func sendMessage(_ text: String) {
128
+ DispatchQueue.main.async { [weak self] in self?.sdk?.sendMessage(text) }
129
+ }
130
+
131
+ @objc public func retryMessage(_ messageId: String) {
132
+ DispatchQueue.main.async { [weak self] in self?.sdk?.retryMessage(messageId: messageId) }
133
+ }
134
+
135
+ @objc(attachFile:resolver:rejecter:)
136
+ public func attachFile(_ opts: NSDictionary,
137
+ resolver: @escaping RCTPromiseResolveBlock,
138
+ rejecter: @escaping RCTPromiseRejectBlock) {
139
+ guard let sdk = sdk else {
140
+ rejecter("E_NOT_CONFIGURED", "configure() must be called first", nil)
141
+ return
142
+ }
143
+ guard let uri = opts["uri"] as? String,
144
+ let name = opts["name"] as? String,
145
+ let mimeType = opts["mimeType"] as? String,
146
+ let url = URL(string: uri) else {
147
+ rejecter("E_ARGS", "uri, name, mimeType are required", nil)
148
+ return
149
+ }
150
+ DispatchQueue.global(qos: .userInitiated).async {
151
+ do {
152
+ let data = try Data(contentsOf: url)
153
+ DispatchQueue.main.async {
154
+ sdk.attachFile(data: data, name: name, mimeType: mimeType, previewUri: uri)
155
+ resolver(nil)
156
+ }
157
+ } catch {
158
+ rejecter("E_READ", "Failed to read file: \(error.localizedDescription)", error)
159
+ }
160
+ }
161
+ }
162
+
163
+ @objc public func destroy() {
164
+ DispatchQueue.main.async { [weak self] in
165
+ guard let self = self else { return }
166
+ self.sdk?.destroy()
167
+ self.sdk = nil
168
+ self.pendingUser = nil
169
+ }
170
+ }
171
+
172
+ // MARK: - LiveAndAiChatDelegate
173
+
174
+ public func didReceiveMessage(_ message: ChatMessage) {
175
+ emitter?.emitEvent("messageReceived", body: Self.chatMessageToDict(message))
176
+ }
177
+ public func didSendMessage(_ message: ChatMessage) {
178
+ emitter?.emitEvent("messageSent", body: Self.chatMessageToDict(message))
179
+ }
180
+ public func agentTypingDidChange(_ isTyping: Bool) {
181
+ emitter?.emitEvent("agentTypingChanged", body: isTyping)
182
+ }
183
+ public func connectionStateDidChange(_ state: ConnectionState) {
184
+ emitter?.emitEvent("connectionStateChanged", body: Self.connectionStateName(state))
185
+ }
186
+ public func didEncounterError(_ error: LiveAndAiChatError) {
187
+ emitter?.emitEvent("error", body: [
188
+ "type": Self.errorTypeName(error.type),
189
+ "message": error.message,
190
+ "recoverable": error.recoverable,
191
+ ])
192
+ }
193
+
194
+ // MARK: - Helpers
195
+
196
+ private static func chatMessageToDict(_ m: ChatMessage) -> [String: Any?] {
197
+ return [
198
+ "id": m.id,
199
+ "clientId": m.clientId,
200
+ "conversationId": m.conversationId,
201
+ "content": m.content,
202
+ "type": m.type.rawValue,
203
+ "status": m.status.rawValue,
204
+ "seq": m.seq,
205
+ "sentAt": m.createdAt,
206
+ "senderName": m.sender?.senderName,
207
+ "totalMessages": m.totalMessages,
208
+ ]
209
+ }
210
+
211
+ private static func connectionStateName(_ state: ConnectionState) -> String {
212
+ switch state {
213
+ case .idle: return "idle"
214
+ case .connecting: return "connecting"
215
+ case .connected: return "connected"
216
+ case .disconnected: return "disconnected"
217
+ case .offline: return "offline"
218
+ }
219
+ }
220
+
221
+ private static func errorTypeName(_ t: ChatErrorType) -> String {
222
+ switch t {
223
+ case .network: return "network"
224
+ case .validation: return "validation"
225
+ case .auth: return "auth"
226
+ case .system: return "system"
227
+ }
228
+ }
229
+
230
+ private func topPresentedViewController() -> UIViewController? {
231
+ let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
232
+ let keyWindow = scenes
233
+ .flatMap { $0.windows }
234
+ .first(where: { $0.isKeyWindow }) ?? scenes.first?.windows.first
235
+ guard var top = keyWindow?.rootViewController else { return nil }
236
+ while let presented = top.presentedViewController { top = presented }
237
+ return top
238
+ }
239
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+
5
+ /**
6
+ * TurboModule spec for the LiveAndAiChat React Native bridge. Codegen
7
+ * produces native protocol stubs from this file:
8
+ * - iOS: ios/build/.../NewinstanceChatSpec/NewinstanceChatSpec.h
9
+ * - Android: android/build/.../NativeNewinstanceChatSpec.java
10
+ *
11
+ * Dict-shaped arguments use `Object` because Codegen can't enforce
12
+ * deep object schemas; the JS class enforces the shapes via TypeScript
13
+ * before calling in.
14
+ */
15
+
16
+ export default TurboModuleRegistry.getEnforcing('NewinstanceChat');
17
+ //# sourceMappingURL=NativeNewinstanceChat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeNewinstanceChat.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,iBAAiB,CAAC","ignoreList":[]}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ import { NativeEventEmitter, NativeModules } from 'react-native';
4
+ import NativeNewinstanceChat from "./NativeNewinstanceChat.js";
5
+ // Bridge mode (old arch) exposes the module on NativeModules; new arch
6
+ // goes through TurboModuleRegistry. NativeEventEmitter accepts either —
7
+ // we feed it the legacy handle so listener counts get tracked.
8
+ const emitterSource = NativeModules.NewinstanceChat ?? NativeNewinstanceChat;
9
+ const emitter = new NativeEventEmitter(emitterSource);
10
+
11
+ /**
12
+ * React Native binding for the native LiveAndAiChat iOS / Android SDKs.
13
+ *
14
+ * Construct, optionally set a user, call `initialize()`, then `openChat()`
15
+ * when the host wants to surface the native chat screen. Subscribe to
16
+ * events with `addListener` — the returned function unsubscribes.
17
+ *
18
+ * Multiple `new NewinstanceChat(...)` calls reconfigure the same underlying
19
+ * native instance — the most recent `configure` wins.
20
+ */
21
+ export class NewinstanceChat {
22
+ /** Resolves once the native SDK is configured. */
23
+
24
+ constructor(config) {
25
+ this.ready = NativeNewinstanceChat.configure(config);
26
+ }
27
+
28
+ /**
29
+ * Identify the customer. Safe to call before or after `initialize()`. If
30
+ * called before `configure()` resolves, the user is queued and applied
31
+ * once the native instance exists.
32
+ */
33
+ setUser(user) {
34
+ NativeNewinstanceChat.setUser(user);
35
+ }
36
+
37
+ /**
38
+ * Fetch org config, restore the saved conversation, and connect the
39
+ * subscription transport in the background. Concurrent callers share
40
+ * the same in-flight init.
41
+ */
42
+ initialize() {
43
+ return NativeNewinstanceChat.initialize();
44
+ }
45
+
46
+ /** Present the native chat screen modally over the current RN host. */
47
+ openChat() {
48
+ NativeNewinstanceChat.openChat();
49
+ }
50
+
51
+ /** Dismiss the native chat screen. */
52
+ closeChat() {
53
+ NativeNewinstanceChat.closeChat();
54
+ }
55
+ sendMessage(text) {
56
+ NativeNewinstanceChat.sendMessage(text);
57
+ }
58
+ retryMessage(messageId) {
59
+ NativeNewinstanceChat.retryMessage(messageId);
60
+ }
61
+
62
+ /**
63
+ * Queue a local file as an attachment. The native side reads bytes from
64
+ * `uri`, pushes them through the SDK's upload pipeline, and bundles the
65
+ * uploaded reference into the next `sendMessage()`.
66
+ */
67
+ attachFile(opts) {
68
+ return NativeNewinstanceChat.attachFile(opts);
69
+ }
70
+
71
+ /**
72
+ * Subscribe to a native event. Returns an unsubscribe function — call it
73
+ * when your component unmounts to avoid leaks.
74
+ */
75
+ addListener(event, handler) {
76
+ const sub = emitter.addListener(event, handler);
77
+ return () => sub.remove();
78
+ }
79
+
80
+ /**
81
+ * Tear down the native SDK. After this the instance is unusable —
82
+ * construct a new one if you need to chat again.
83
+ */
84
+ destroy() {
85
+ NativeNewinstanceChat.destroy();
86
+ }
87
+ }
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NativeEventEmitter","NativeModules","NativeNewinstanceChat","emitterSource","NewinstanceChat","emitter","constructor","config","ready","configure","setUser","user","initialize","openChat","closeChat","sendMessage","text","retryMessage","messageId","attachFile","opts","addListener","event","handler","sub","remove","destroy"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,kBAAkB,EAClBC,aAAa,QAER,cAAc;AAErB,OAAOC,qBAAqB,MAAM,4BAAyB;AAqB3D;AACA;AACA;AACA,MAAMC,aAAkB,GACtBF,aAAa,CAACG,eAAe,IAAKF,qBAAiC;AACrE,MAAMG,OAAO,GAAG,IAAIL,kBAAkB,CAACG,aAAa,CAAC;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,CAAC;EAC3B;;EAGAE,WAAWA,CAACC,MAA6B,EAAE;IACzC,IAAI,CAACC,KAAK,GAAGN,qBAAqB,CAACO,SAAS,CAACF,MAAM,CAAC;EACtD;;EAEA;AACF;AACA;AACA;AACA;EACEG,OAAOA,CAACC,IAAc,EAAQ;IAC5BT,qBAAqB,CAACQ,OAAO,CAACC,IAAI,CAAC;EACrC;;EAEA;AACF;AACA;AACA;AACA;EACEC,UAAUA,CAAA,EAAkB;IAC1B,OAAOV,qBAAqB,CAACU,UAAU,CAAC,CAAC;EAC3C;;EAEA;EACAC,QAAQA,CAAA,EAAS;IACfX,qBAAqB,CAACW,QAAQ,CAAC,CAAC;EAClC;;EAEA;EACAC,SAASA,CAAA,EAAS;IAChBZ,qBAAqB,CAACY,SAAS,CAAC,CAAC;EACnC;EAEAC,WAAWA,CAACC,IAAY,EAAQ;IAC9Bd,qBAAqB,CAACa,WAAW,CAACC,IAAI,CAAC;EACzC;EAEAC,YAAYA,CAACC,SAAiB,EAAQ;IACpChB,qBAAqB,CAACe,YAAY,CAACC,SAAS,CAAC;EAC/C;;EAEA;AACF;AACA;AACA;AACA;EACEC,UAAUA,CAACC,IAAqB,EAAiB;IAC/C,OAAOlB,qBAAqB,CAACiB,UAAU,CAACC,IAAI,CAAC;EAC/C;;EAEA;AACF;AACA;AACA;EACEC,WAAWA,CACTC,KAAQ,EACRC,OAAwB,EACZ;IACZ,MAAMC,GAAwB,GAAGnB,OAAO,CAACgB,WAAW,CAClDC,KAAK,EACLC,OACF,CAAC;IACD,OAAO,MAAMC,GAAG,CAACC,MAAM,CAAC,CAAC;EAC3B;;EAEA;AACF;AACA;AACA;EACEC,OAAOA,CAAA,EAAS;IACdxB,qBAAqB,CAACwB,OAAO,CAAC,CAAC;EACjC;AACF","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,27 @@
1
+ import { type TurboModule } from 'react-native';
2
+ /**
3
+ * TurboModule spec for the LiveAndAiChat React Native bridge. Codegen
4
+ * produces native protocol stubs from this file:
5
+ * - iOS: ios/build/.../NewinstanceChatSpec/NewinstanceChatSpec.h
6
+ * - Android: android/build/.../NativeNewinstanceChatSpec.java
7
+ *
8
+ * Dict-shaped arguments use `Object` because Codegen can't enforce
9
+ * deep object schemas; the JS class enforces the shapes via TypeScript
10
+ * before calling in.
11
+ */
12
+ export interface Spec extends TurboModule {
13
+ configure(config: Object): Promise<void>;
14
+ setUser(user: Object): void;
15
+ initialize(): Promise<void>;
16
+ openChat(): void;
17
+ closeChat(): void;
18
+ sendMessage(text: string): void;
19
+ retryMessage(messageId: string): void;
20
+ attachFile(opts: Object): Promise<void>;
21
+ destroy(): void;
22
+ addListener(eventName: string): void;
23
+ removeListeners(count: number): void;
24
+ }
25
+ declare const _default: Spec;
26
+ export default _default;
27
+ //# sourceMappingURL=NativeNewinstanceChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeNewinstanceChat.d.ts","sourceRoot":"","sources":["../../../src/NativeNewinstanceChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE;;;;;;;;;GASG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,IAAI,IAAI,CAAC;IACjB,SAAS,IAAI,IAAI,CAAC;IAClB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,IAAI,IAAI,CAAC;IAIhB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAyE"}
@@ -0,0 +1,52 @@
1
+ import type { AttachmentInput, ChatUser, EventHandler, EventName, NewinstanceChatConfig } from './types';
2
+ export type { AttachmentInput, ChatMessage, ChatUser, ConnectionState, EventMap, EventName, NewinstanceChatConfig, NewinstanceChatError, NewinstanceChatErrorType, } from './types';
3
+ /**
4
+ * React Native binding for the native LiveAndAiChat iOS / Android SDKs.
5
+ *
6
+ * Construct, optionally set a user, call `initialize()`, then `openChat()`
7
+ * when the host wants to surface the native chat screen. Subscribe to
8
+ * events with `addListener` — the returned function unsubscribes.
9
+ *
10
+ * Multiple `new NewinstanceChat(...)` calls reconfigure the same underlying
11
+ * native instance — the most recent `configure` wins.
12
+ */
13
+ export declare class NewinstanceChat {
14
+ /** Resolves once the native SDK is configured. */
15
+ readonly ready: Promise<void>;
16
+ constructor(config: NewinstanceChatConfig);
17
+ /**
18
+ * Identify the customer. Safe to call before or after `initialize()`. If
19
+ * called before `configure()` resolves, the user is queued and applied
20
+ * once the native instance exists.
21
+ */
22
+ setUser(user: ChatUser): void;
23
+ /**
24
+ * Fetch org config, restore the saved conversation, and connect the
25
+ * subscription transport in the background. Concurrent callers share
26
+ * the same in-flight init.
27
+ */
28
+ initialize(): Promise<void>;
29
+ /** Present the native chat screen modally over the current RN host. */
30
+ openChat(): void;
31
+ /** Dismiss the native chat screen. */
32
+ closeChat(): void;
33
+ sendMessage(text: string): void;
34
+ retryMessage(messageId: string): void;
35
+ /**
36
+ * Queue a local file as an attachment. The native side reads bytes from
37
+ * `uri`, pushes them through the SDK's upload pipeline, and bundles the
38
+ * uploaded reference into the next `sendMessage()`.
39
+ */
40
+ attachFile(opts: AttachmentInput): Promise<void>;
41
+ /**
42
+ * Subscribe to a native event. Returns an unsubscribe function — call it
43
+ * when your component unmounts to avoid leaks.
44
+ */
45
+ addListener<K extends EventName>(event: K, handler: EventHandler<K>): () => void;
46
+ /**
47
+ * Tear down the native SDK. After this the instance is unusable —
48
+ * construct a new one if you need to chat again.
49
+ */
50
+ destroy(): void;
51
+ }
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,eAAe,EACf,WAAW,EACX,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,SAAS,EACT,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,SAAS,CAAC;AASjB;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAElB,MAAM,EAAE,qBAAqB;IAIzC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAI7B;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,uEAAuE;IACvE,QAAQ,IAAI,IAAI;IAIhB,sCAAsC;IACtC,SAAS,IAAI,IAAI;IAIjB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD;;;OAGG;IACH,WAAW,CAAC,CAAC,SAAS,SAAS,EAC7B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GACvB,MAAM,IAAI;IAQb;;;OAGG;IACH,OAAO,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Public types for `react-native-newinstance-chat`.
3
+ *
4
+ * Shapes match what the native bridges produce, normalised across
5
+ * iOS / Android (e.g. message status / error type / connection state
6
+ * are lowercased string enums, not platform-specific enum values).
7
+ */
8
+ export interface NewinstanceChatConfig {
9
+ /** API key id from your newinstance.cloud dashboard. Never embed the secret half. */
10
+ apiKey: string;
11
+ /** Backend base URL. Defaults to `https://service.newinstance.cloud`. */
12
+ baseUrl?: string;
13
+ /** Subscription transport. `'sse'` (default in production), `'ws'`, or omit to let the server choose. */
14
+ transport?: 'sse' | 'ws';
15
+ /** Optional message pre-seeded as the first outbound message. */
16
+ initialMessage?: string;
17
+ }
18
+ export interface ChatUser {
19
+ customerName: string;
20
+ customerEmail?: string;
21
+ customerId?: string;
22
+ }
23
+ /** A local file the native side reads bytes from. */
24
+ export interface AttachmentInput {
25
+ /** Local file URI: `file://...` (iOS) or `content://...` / `file://...` (Android). */
26
+ uri: string;
27
+ name: string;
28
+ mimeType: string;
29
+ }
30
+ export type ConnectionState = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'offline';
31
+ export interface ChatMessage {
32
+ id: string;
33
+ /** Client-side id used to dedupe a sent message against its server echo. */
34
+ clientId?: string;
35
+ conversationId: string;
36
+ content: string;
37
+ /** Lowercased enum from the native side: `'text'`, `'image'`, etc. */
38
+ type: string;
39
+ /** Lowercased enum: `'sent'`, `'delivered'`, `'failed'`, etc. */
40
+ status: string;
41
+ /** Server-assigned monotonic sequence number for ordering. */
42
+ seq?: number;
43
+ /** ISO-8601 timestamp string. */
44
+ sentAt?: string;
45
+ /**
46
+ * Total persisted messages in the conversation as of this envelope.
47
+ * Only present on `messageReceived`. The SDK uses this for silent
48
+ * gap-fill — if the locally-rendered count is below this, it refetches.
49
+ */
50
+ totalMessages?: number;
51
+ }
52
+ export type NewinstanceChatErrorType = 'network' | 'validation' | 'auth' | 'system';
53
+ export interface NewinstanceChatError {
54
+ type: NewinstanceChatErrorType;
55
+ message: string;
56
+ recoverable: boolean;
57
+ }
58
+ /** Native event names. Subscribe with `sdk.addListener(event, handler)`. */
59
+ export interface EventMap {
60
+ messageReceived: (message: ChatMessage) => void;
61
+ messageSent: (message: ChatMessage) => void;
62
+ agentTypingChanged: (isTyping: boolean) => void;
63
+ connectionStateChanged: (state: ConnectionState) => void;
64
+ unreadCountChanged: (count: number) => void;
65
+ error: (e: NewinstanceChatError) => void;
66
+ }
67
+ export type EventName = keyof EventMap;
68
+ export type EventHandler<K extends EventName> = EventMap[K];
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yGAAyG;IACzG,SAAS,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACzB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,YAAY,GACZ,WAAW,GACX,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,wBAAwB,GAChC,SAAS,GACT,YAAY,GACZ,MAAM,GACN,QAAQ,CAAC;AAEb,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,4EAA4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,WAAW,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5C,kBAAkB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,sBAAsB,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACzD,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC;AACvC,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC"}