signalbird 1.4.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.
package/dist/app.d.ts ADDED
@@ -0,0 +1,343 @@
1
+ /**
2
+ * Uygulama (son kullanıcı) yüzeyinin tipleri.
3
+ *
4
+ * Bu yüzey MÜŞTERİNİN MÜŞTERİSİ içindir: ziyaretçi ya da uygulama kullanıcısı.
5
+ * Anahtarı açıktır (`sbw_pub_…`) ve istemciye gömülür; güvenliği gizlilikten
6
+ * değil kısıttan gelir — yalnız izinli kökenden çalışır ve yalnız ziyaretçinin
7
+ * KENDİ verisine dokunur.
8
+ */
9
+ interface SbResult<T = unknown> {
10
+ ok: boolean;
11
+ status: number;
12
+ data?: T;
13
+ code?: string;
14
+ message?: string;
15
+ }
16
+ /**
17
+ * Ziyaretçi kimliğinin saklandığı yer.
18
+ *
19
+ * Tarayıcıda `localStorage`, React Native'de `AsyncStorage`, sunucu tarafı
20
+ * testte bellek. Arayüz eşzamansızdır çünkü mobil depolar öyledir; eşzamanlı
21
+ * tanımlansaydı React Native uyarlaması mümkün olmazdı.
22
+ */
23
+ interface AppStorage {
24
+ getItem(key: string): Promise<string | null> | string | null;
25
+ setItem(key: string, value: string): Promise<void> | void;
26
+ removeItem(key: string): Promise<void> | void;
27
+ }
28
+ interface AppConfig {
29
+ /** Uygulama anahtarı (`sbw_pub_…`). Panelden ya da `createApp` ile alınır. */
30
+ appKey: string;
31
+ /** Varsayılan: https://signalbird.io/api */
32
+ baseUrl?: string;
33
+ /** `tr` ya da `en`; verilmezse uygulamanın ayarı, sonra cihazın dili. */
34
+ locale?: string;
35
+ /** Ziyaretçi sırrının saklandığı yer. Varsayılan: web'de localStorage, yoksa bellek. */
36
+ storage?: AppStorage;
37
+ /** İstek zaman aşımı (ms). Varsayılan 10000. */
38
+ timeout?: number;
39
+ /** Açıksa konsola yazar. */
40
+ debug?: boolean;
41
+ /** Özel `fetch` (React Native polyfill, test sahtesi). */
42
+ fetchImpl?: typeof fetch;
43
+ }
44
+ /** `POST /v1/sdk/bootstrap` yanıtı — widget çizilmeden önceki tek soru. */
45
+ interface BootstrapResult {
46
+ app: {
47
+ id: number;
48
+ name: string;
49
+ chat_enabled: boolean;
50
+ push_enabled: boolean;
51
+ locale?: string;
52
+ within_hours?: boolean;
53
+ offline_message?: string | null;
54
+ chat?: {
55
+ color?: string;
56
+ position?: string;
57
+ launcher_text?: string;
58
+ welcome_message?: string;
59
+ max_attachment_mb?: number;
60
+ sound?: boolean;
61
+ locale?: string;
62
+ prechat?: {
63
+ name?: boolean;
64
+ email?: boolean;
65
+ };
66
+ };
67
+ };
68
+ }
69
+ interface Visitor {
70
+ id: string;
71
+ /** Ziyaretçi sırrı — YALNIZ oturum açılışında döner, sonra saklanır. */
72
+ secret?: string;
73
+ name?: string | null;
74
+ email?: string | null;
75
+ phone?: string | null;
76
+ external_id?: string | null;
77
+ unread_count?: number;
78
+ }
79
+ interface SessionInput {
80
+ name?: string;
81
+ email?: string;
82
+ phone?: string;
83
+ external_id?: string;
84
+ attributes?: Record<string, unknown>;
85
+ page_url?: string;
86
+ }
87
+ interface IdentifyInput {
88
+ external_id?: string;
89
+ email?: string;
90
+ name?: string;
91
+ phone?: string;
92
+ attributes?: Record<string, unknown>;
93
+ }
94
+ type MessageSender = 'visitor' | 'agent' | 'system';
95
+ interface Message {
96
+ id: string;
97
+ sender_type: MessageSender;
98
+ body?: string | null;
99
+ attachments?: Attachment[] | null;
100
+ reply_to_id?: string | null;
101
+ reactions?: Record<string, string[]> | null;
102
+ delivered_at?: string | null;
103
+ read_at?: string | null;
104
+ edited_at?: string | null;
105
+ created_at?: string;
106
+ /** İyimser gönderimde yerel kopyayı sunucudakiyle eşleştirir. */
107
+ client_id?: string | null;
108
+ }
109
+ interface Attachment {
110
+ id?: string;
111
+ name?: string;
112
+ url?: string;
113
+ mime?: string;
114
+ size?: number;
115
+ }
116
+ interface Conversation {
117
+ id: string;
118
+ status: string;
119
+ subject?: string | null;
120
+ unread_count?: number;
121
+ agent_typing?: boolean;
122
+ within_hours?: boolean;
123
+ last_message_at?: string | null;
124
+ messages?: Message[];
125
+ }
126
+ interface StartConversationInput {
127
+ body: string;
128
+ /** İyimser gönderim anahtarı: aynı `client_id` ikinci kez konuşma AÇMAZ. */
129
+ client_id?: string;
130
+ attachments?: unknown[];
131
+ page_url?: string;
132
+ }
133
+ interface SendMessageInput {
134
+ body?: string;
135
+ client_id?: string;
136
+ reply_to_id?: string | null;
137
+ attachments?: unknown[];
138
+ }
139
+ interface ConversationQuery {
140
+ /** `cm_…` imleci — yalnız bundan sonrakiler döner. */
141
+ after?: string;
142
+ limit?: number;
143
+ }
144
+ type DevicePlatform = 'ios' | 'android' | 'web';
145
+ interface RegisterDeviceInput {
146
+ token: string;
147
+ platform: DevicePlatform;
148
+ provider?: 'fcm' | 'apns' | 'webpush' | string;
149
+ external_id?: string;
150
+ device_name?: string;
151
+ app_version?: string;
152
+ locale?: string;
153
+ }
154
+
155
+ /**
156
+ * Uygulama istemcisi — son kullanıcı tarafı (sohbet + push kaydı).
157
+ *
158
+ * Tek bir sınıf; tarayıcı, React Native, Electron ve test aynı gövdeyi kullanır.
159
+ * Platform farkı iki noktada toplanmıştır ve ikisi de dışarıdan verilir:
160
+ * `storage` (ziyaretçi sırrı nerede durur) ve `fetchImpl`. Çatıya özel sarmalayıcı
161
+ * yazmak yerine bunu seçtik — React, Vue, Angular ve RN uyarlamaları bu sınıfın
162
+ * ÜSTÜNE oturur, kopyası değildir.
163
+ *
164
+ * Kimlik iki parçadır: açık uygulama anahtarı (`X-Signalbird-App-Key`) ve
165
+ * ziyaretçi sırrı (`X-Signalbird-Visitor`). Sır yalnız oturum açılışında döner;
166
+ * kaybolursa yeni oturum açılır ve geçmiş konuşmalar görünmez — bu yüzden
167
+ * saklama katmanı zorunludur, isteğe bağlı değil.
168
+ *
169
+ * Hiçbir metot istisna fırlatmaz: sohbet balonunun hatası müşterinin ödeme
170
+ * sayfasını çökertmemeli. Sonuç her zaman `{ok, status, …}` zarfıdır.
171
+ *
172
+ * Sözleşme: docs/CONTRACT.md § 11
173
+ */
174
+
175
+ /** RFC 4122 uyumlu olmak zorunda değil; tek işi yerel kopyayı eşlemek. */
176
+ declare function clientId(): string;
177
+ declare class SignalbirdApp {
178
+ private readonly config;
179
+ private readonly baseUrl;
180
+ private readonly storage;
181
+ private readonly timeout;
182
+ private readonly doFetch;
183
+ private visitor;
184
+ private loaded;
185
+ constructor(config: AppConfig);
186
+ /** Uygulama ayarları: sohbet açık mı, renk, çalışma saati, ön-form. */
187
+ bootstrap(): Promise<SbResult<BootstrapResult>>;
188
+ /**
189
+ * Ziyaretçi oturumu açar ya da mevcut olanı günceller.
190
+ *
191
+ * Sır saklanır; ikinci çağrı aynı ziyaretçiyi tazeler. Sunucu `VISITOR_INVALID`
192
+ * derse yerel kimlik silinir ve bir sonraki çağrı yeni oturum açar.
193
+ */
194
+ startSession(input?: SessionInput): Promise<SbResult<{
195
+ visitor: Visitor;
196
+ }>>;
197
+ /** Oturum açmış kullanıcıyı ziyaretçiye bağlar (kişi kaydı upsert edilir). */
198
+ identify(input: IdentifyInput): Promise<SbResult<{
199
+ visitor: Visitor;
200
+ }>>;
201
+ /** Saklanan ziyaretçi kimliği — yoksa `null`. */
202
+ currentVisitor(): Promise<{
203
+ id: string;
204
+ name?: string | null;
205
+ email?: string | null;
206
+ } | null>;
207
+ /** Yerel kimliği siler: çıkış yapıldığında çağrılır. Sunucudaki kayıt kalır. */
208
+ signOut(): Promise<void>;
209
+ listConversations(): Promise<SbResult<{
210
+ data: Conversation[];
211
+ }>>;
212
+ getConversation(id: string, query?: ConversationQuery): Promise<SbResult<{
213
+ conversation: Conversation;
214
+ }>>;
215
+ /**
216
+ * İlk mesajla konuşma açar. Kota burada harcanır — konuşma başına sayılır,
217
+ * mesaj başına değil.
218
+ */
219
+ startConversation(input: StartConversationInput): Promise<SbResult<{
220
+ conversation: Conversation;
221
+ message: Message;
222
+ }>>;
223
+ sendMessage(conversationId: string, input: SendMessageInput): Promise<SbResult<{
224
+ message: Message;
225
+ }>>;
226
+ /** Yalnız kendi mesajı ve gönderimden sonraki 15 dakika içinde. */
227
+ editMessage(conversationId: string, messageId: string, body: string): Promise<SbResult<{
228
+ message: Message;
229
+ }>>;
230
+ deleteMessage(conversationId: string, messageId: string): Promise<SbResult<unknown>>;
231
+ /** Aynı emoji ikinci kez gönderilirse tepki kaldırılır. */
232
+ reactToMessage(conversationId: string, messageId: string, emoji: string): Promise<SbResult<{
233
+ message: Message;
234
+ }>>;
235
+ setTyping(conversationId: string, isTyping: boolean): Promise<SbResult<unknown>>;
236
+ markRead(conversationId: string, lastMessageId?: string): Promise<SbResult<unknown>>;
237
+ /**
238
+ * Ek dosya yükler; dönen tanımlayıcı `sendMessage`'a `attachments` içinde
239
+ * verilir. İki adım olmasının sebebi: dosya yüklenirken mesaj metni hâlâ
240
+ * yazılıyor olabilir ve yarım kalan yükleme mesaj kaydı yaratmamalı.
241
+ */
242
+ uploadAttachment(conversationId: string, file: unknown, fileName?: string): Promise<SbResult<{
243
+ attachment: unknown;
244
+ }>>;
245
+ closeConversation(conversationId: string): Promise<SbResult<{
246
+ conversation: Conversation;
247
+ }>>;
248
+ rateConversation(conversationId: string, rating: number, comment?: string): Promise<SbResult<unknown>>;
249
+ /**
250
+ * Cihaz token'ını kaydeder. Token'ı almak (FCM/APNs/Web Push izni) ev
251
+ * sahibinin işidir; SDK yalnız iletir — izin diyaloğunu kimin, ne zaman
252
+ * göstereceği ürün kararıdır, kütüphane kararı değil.
253
+ */
254
+ registerDevice(input: RegisterDeviceInput): Promise<SbResult<unknown>>;
255
+ /** Çıkışta çağrılır: kayıt silinmez, kapatılır (geçmiş korunur). */
256
+ unregisterDevice(token: string): Promise<SbResult<unknown>>;
257
+ private request;
258
+ private loadVisitor;
259
+ private storeVisitor;
260
+ }
261
+
262
+ /**
263
+ * Sohbet oturumu — çatısız durum yönetimi.
264
+ *
265
+ * `SignalbirdApp` ham uçları verir; burası bir sohbet ekranının gerçekten
266
+ * ihtiyaç duyduğu şeyi verir: mesaj listesi, okunmamış sayısı, yazıyor durumu,
267
+ * iyimser gönderim ve yoklama merdiveni. React/Vue/Angular/React Native
268
+ * uyarlamaları bu sınıfa abone olur — üçünde de aynı mantığı yeniden yazmak,
269
+ * üç ayrı hata takımı üretmek demekti.
270
+ *
271
+ * Yoklama merdiveni (penyu deseni): panel açıkken 3 s, kapalıyken 20 s ×3 →
272
+ * 60 s ×2 → 180 s. Yeni veri merdiveni sıfırlar; sekme/uygulama arka plandayken
273
+ * tur atlanır. WebSocket yoktur: imleçli yoklama, bağlantı kopmasında kendi
274
+ * kendini toparlar ve mobil ağda pil yakmaz.
275
+ */
276
+
277
+ interface ChatState {
278
+ /** Sohbet bu uygulamada açık mı (`bootstrap` cevabı). */
279
+ enabled: boolean;
280
+ loading: boolean;
281
+ conversation: Conversation | null;
282
+ messages: Message[];
283
+ unread: number;
284
+ agentTyping: boolean;
285
+ withinHours: boolean;
286
+ /** Son hatanın kodu — arayüz isterse gösterir, göstermezse yutar. */
287
+ errorCode?: string;
288
+ }
289
+ type ChatListener = (state: ChatState) => void;
290
+ interface ChatSessionOptions {
291
+ /** Panel açık mı — yoklama hızını belirler. */
292
+ active?: boolean;
293
+ /** Arka plandayken tur atlanır; varsayılan: `document.visibilityState`. */
294
+ isVisible?: () => boolean;
295
+ /** Açılışta oturum kurulurken kullanılacak ziyaretçi bilgisi. */
296
+ visitor?: SessionInput;
297
+ }
298
+ declare class ChatSession {
299
+ private readonly app;
300
+ private readonly options;
301
+ private state;
302
+ private listeners;
303
+ private timer;
304
+ private step;
305
+ private active;
306
+ private stopped;
307
+ private polling;
308
+ constructor(app: SignalbirdApp, options?: ChatSessionOptions);
309
+ subscribe(listener: ChatListener): () => void;
310
+ snapshot(): ChatState;
311
+ /** Bootstrap + varsa mevcut konuşmayı yükler, sonra yoklamayı başlatır. */
312
+ start(): Promise<void>;
313
+ /** Panel açıldı/kapandı — yoklama hızı buna göre değişir. */
314
+ setActive(active: boolean): void;
315
+ stop(): void;
316
+ /** Ön-form gönderildiğinde ya da uygulama kullanıcıyı tanıdığında. */
317
+ openSession(input: SessionInput): Promise<SbResult<unknown>>;
318
+ /**
319
+ * Mesaj gönderir. Konuşma yoksa açar.
320
+ *
321
+ * İyimser: mesaj listeye ANINDA düşer, `client_id` ile eşlenir. Sunucu
322
+ * cevabı gelince yerel kopya onunla değiştirilir; başarısızsa `failed`
323
+ * işaretlenir ve arayüz "yeniden dene" gösterebilir.
324
+ */
325
+ send(body: string, attachments?: unknown[]): Promise<SbResult<unknown>>;
326
+ /** İlk tuşta `true`, 2.5 s hareketsizlikte `false` — çağıran zamanlar. */
327
+ typing(isTyping: boolean): void;
328
+ /** Görülen son mesaja kadar okundu işaretler. */
329
+ markRead(): Promise<void>;
330
+ close(rating?: number, comment?: string): Promise<void>;
331
+ /** Sunucudaki durumu çeker; imleç varsa yalnız yenileri ister. */
332
+ refresh(): Promise<void>;
333
+ private applyConversation;
334
+ /** İyimser kayıtlar sunucu kimliği taşımaz; imleç yalnız gerçek kimliktir. */
335
+ private lastServerMessageId;
336
+ private markFailed;
337
+ private schedule;
338
+ private tick;
339
+ private visible;
340
+ private patch;
341
+ }
342
+
343
+ export { type AppConfig, type AppStorage, type Attachment, type BootstrapResult, type ChatListener, ChatSession, type ChatSessionOptions, type ChatState, type Conversation, type ConversationQuery, type DevicePlatform, type IdentifyInput, type Message, type MessageSender, type RegisterDeviceInput, type SbResult, type SendMessageInput, type SessionInput, SignalbirdApp, type StartConversationInput, type Visitor, clientId };