signalbird 2.3.0 → 2.3.2

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/README.md CHANGED
@@ -94,7 +94,7 @@ değil, kasıtlı bir duvardır — anahtar bir kez istemciye indiğinde herkesi
94
94
  | Go | `go get github.com/Pariette-Inc/signalbird.sdk` |
95
95
  | .NET, ASP.NET Core | `dotnet add package Signalbird.Sdk` |
96
96
  | Swift (iOS, macOS) | SPM: `https://github.com/Pariette-Inc/signalbird.sdk` |
97
- | Kotlin (Android) | `implementation("io.signalbird:signalbird-sdk:2.3.0")` |
97
+ | Kotlin (Android) | `implementation("io.signalbird:signalbird-sdk:2.3.2")` |
98
98
  | Canlı sohbet widget'ı (herhangi bir site) | `<script async src="https://signalbird.io/sdk/v1/signalbird.js" data-key="sb_public_live_…" data-channel="destek"></script>` |
99
99
 
100
100
  > Hepsi **bu repodan** çıkar ve **aynı sürümü** taşır — ayrı SDK reposu ya da
package/dist/angular.js CHANGED
@@ -514,7 +514,7 @@ var ChatSession = class {
514
514
  async start() {
515
515
  this.stopped = false;
516
516
  const boot = await this.app.bootstrap();
517
- const app = boot.data?.app;
517
+ const app = boot.data?.channel ?? boot.data?.app;
518
518
  if (!boot.ok || !app?.chat_enabled) {
519
519
  this.patch({ enabled: false, loading: false, errorCode: boot.code });
520
520
  return;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/app/client.ts","../src/shared/socket.ts","../src/app/session.ts","../src/angular/index.ts"],"names":["detail","BehaviorSubject"],"mappings":"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","file":"angular.js","sourcesContent":["/**\n * Uygulama istemcisi — son kullanıcı tarafı (sohbet + push kaydı).\n *\n * Tek bir sınıf; tarayıcı, React Native, Electron ve test aynı gövdeyi kullanır.\n * Platform farkı iki noktada toplanmıştır ve ikisi de dışarıdan verilir:\n * `storage` (ziyaretçi sırrı nerede durur) ve `fetchImpl`. Çatıya özel sarmalayıcı\n * yazmak yerine bunu seçtik — React, Vue, Angular ve RN uyarlamaları bu sınıfın\n * ÜSTÜNE oturur, kopyası değildir.\n *\n * Kimlik iki parçadır: açık domain anahtarı (`X-Signalbird-Key`) ve\n * ziyaretçi sırrı (`X-Signalbird-Visitor`). Sır yalnız oturum açılışında döner;\n * kaybolursa yeni oturum açılır ve geçmiş konuşmalar görünmez — bu yüzden\n * saklama katmanı zorunludur, isteğe bağlı değil.\n *\n * Hiçbir metot istisna fırlatmaz: sohbet balonunun hatası müşterinin ödeme\n * sayfasını çökertmemeli. Sonuç her zaman `{ok, status, …}` zarfıdır.\n *\n * Sözleşme: docs/CONTRACT.md § 11\n */\nimport type {\n AppConfig,\n AppStorage,\n BootstrapResult,\n Conversation,\n ConversationQuery,\n IdentifyInput,\n Message,\n RegisterDeviceInput,\n SbResult,\n SendMessageInput,\n SessionInput,\n StartConversationInput,\n Visitor,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://live.signalbird.io/api';\nconst STORAGE_KEY = 'sb_visitor';\n\ninterface StoredVisitor {\n id: string;\n secret: string;\n publicKey: string;\n name?: string | null;\n email?: string | null;\n}\n\n/** Depo verilmezse: tarayıcıda localStorage, başka yerde bellek. */\nfunction defaultStorage(): AppStorage {\n try {\n if (typeof localStorage !== 'undefined') {\n return {\n getItem: (k) => localStorage.getItem(k),\n setItem: (k, v) => localStorage.setItem(k, v),\n removeItem: (k) => localStorage.removeItem(k),\n };\n }\n } catch {\n // Gizli sekme / kısıtlı iframe — belleğe düş.\n }\n\n const memory = new Map<string, string>();\n\n return {\n getItem: (k) => memory.get(k) ?? null,\n setItem: (k, v) => void memory.set(k, v),\n removeItem: (k) => void memory.delete(k),\n };\n}\n\n/** RFC 4122 uyumlu olmak zorunda değil; tek işi yerel kopyayı eşlemek. */\nexport function clientId(): string {\n try {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n } catch {\n /* yok say */\n }\n\n return `c_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport class SignalbirdApp {\n private readonly baseUrl: string;\n private readonly storage: AppStorage;\n private readonly timeout: number;\n private readonly doFetch: typeof fetch;\n private visitor: StoredVisitor | null = null;\n private loaded = false;\n\n constructor(private readonly config: AppConfig) {\n if (!config?.publicKey) {\n throw new Error('Signalbird: publicKey zorunlu (sb_public_live_…).');\n }\n\n // Takım anahtarı istemciye gömülürse tüm gönderim yetkisi sızar. Sunucu da\n // reddederdi ama o noktada anahtar çoktan yayınlanmış olurdu.\n if (!config.publicKey.startsWith('sb_public_live_')) {\n throw new Error(\n 'Signalbird: uygulama istemcisi açık domain anahtarı ister (sb_public_live_…). ' +\n 'Takım anahtarını (sb_…) istemci koduna KOYMAYIN.'\n );\n }\n\n this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.storage = config.storage ?? defaultStorage();\n this.timeout = config.timeout ?? 10000;\n this.doFetch = config.fetchImpl ?? ((...args) => fetch(...args));\n }\n\n // ── Kimlik ────────────────────────────────────────────────────────────\n\n /** Uygulama ayarları: sohbet açık mı, renk, çalışma saati, ön-form. */\n bootstrap(): Promise<SbResult<BootstrapResult>> {\n return this.request('POST', '/v1/sdk/bootstrap', { locale: this.config.locale });\n }\n\n /**\n * Canlı bağlantı kanalı için imza.\n *\n * Ziyaretçinin oturumu yoktur; hangi kanalı dinleyebileceğine SUNUCU karar\n * verir ve yalnız kendi `visitor.<id>` kanalını imzalar. Soket servisi\n * kimseyi tanımaz, yalnız imzayı doğrular.\n */\n socketAuth(socketId: string, channel: string): Promise<SbResult<{ auth: string; at: number }>> {\n return this.request('POST', '/v1/sdk/chat/socket/auth', { socket_id: socketId, channel });\n }\n\n /**\n * Ziyaretçi oturumu açar ya da mevcut olanı günceller.\n *\n * Sır saklanır; ikinci çağrı aynı ziyaretçiyi tazeler. Sunucu `VISITOR_INVALID`\n * derse yerel kimlik silinir ve bir sonraki çağrı yeni oturum açar.\n */\n async startSession(input: SessionInput = {}): Promise<SbResult<{ visitor: Visitor }>> {\n const result = await this.request<{ visitor: Visitor }>('POST', '/v1/sdk/chat/session', input);\n\n const visitor = result.data?.visitor;\n\n if (result.ok && visitor?.id && visitor.secret) {\n await this.storeVisitor({\n id: visitor.id,\n secret: visitor.secret,\n publicKey: this.config.publicKey,\n name: visitor.name ?? null,\n email: visitor.email ?? null,\n });\n }\n\n return result;\n }\n\n /** Oturum açmış kullanıcıyı ziyaretçiye bağlar (kişi kaydı upsert edilir). */\n identify(input: IdentifyInput): Promise<SbResult<{ visitor: Visitor }>> {\n return this.request('POST', '/v1/sdk/identify', input);\n }\n\n /** Saklanan ziyaretçi kimliği — yoksa `null`. */\n async currentVisitor(): Promise<{ id: string; name?: string | null; email?: string | null } | null> {\n const stored = await this.loadVisitor();\n\n return stored ? { id: stored.id, name: stored.name, email: stored.email } : null;\n }\n\n /** Yerel kimliği siler: çıkış yapıldığında çağrılır. Sunucudaki kayıt kalır. */\n async signOut(): Promise<void> {\n this.visitor = null;\n this.loaded = true;\n await this.storage.removeItem(STORAGE_KEY);\n }\n\n // ── Sohbet ────────────────────────────────────────────────────────────\n\n listConversations(): Promise<SbResult<{ data: Conversation[] }>> {\n return this.request('GET', '/v1/sdk/chat/conversations');\n }\n\n getConversation(id: string, query?: ConversationQuery): Promise<SbResult<{ conversation: Conversation }>> {\n return this.request('GET', `/v1/sdk/chat/conversations/${enc(id)}`, undefined, query);\n }\n\n /**\n * İlk mesajla konuşma açar. Kota burada harcanır — konuşma başına sayılır,\n * mesaj başına değil.\n */\n startConversation(input: StartConversationInput): Promise<SbResult<{ conversation: Conversation; message: Message }>> {\n return this.request('POST', '/v1/sdk/chat/conversations', {\n client_id: clientId(),\n ...input,\n });\n }\n\n sendMessage(conversationId: string, input: SendMessageInput): Promise<SbResult<{ message: Message }>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/messages`, {\n client_id: clientId(),\n ...input,\n });\n }\n\n /** Yalnız kendi mesajı ve gönderimden sonraki 15 dakika içinde. */\n editMessage(conversationId: string, messageId: string, body: string): Promise<SbResult<{ message: Message }>> {\n return this.request(\n 'PATCH',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/messages/${enc(messageId)}`,\n { body }\n );\n }\n\n deleteMessage(conversationId: string, messageId: string): Promise<SbResult<unknown>> {\n return this.request(\n 'DELETE',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/messages/${enc(messageId)}`\n );\n }\n\n /** Aynı emoji ikinci kez gönderilirse tepki kaldırılır. */\n reactToMessage(conversationId: string, messageId: string, emoji: string): Promise<SbResult<{ message: Message }>> {\n return this.request(\n 'POST',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/messages/${enc(messageId)}/reactions`,\n { emoji }\n );\n }\n\n setTyping(conversationId: string, isTyping: boolean): Promise<SbResult<unknown>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/typing`, {\n is_typing: isTyping,\n });\n }\n\n markRead(conversationId: string, lastMessageId?: string): Promise<SbResult<unknown>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/read`, {\n last_message_id: lastMessageId,\n });\n }\n\n /**\n * Ek dosya yükler; dönen tanımlayıcı `sendMessage`'a `attachments` içinde\n * verilir. İki adım olmasının sebebi: dosya yüklenirken mesaj metni hâlâ\n * yazılıyor olabilir ve yarım kalan yükleme mesaj kaydı yaratmamalı.\n */\n uploadAttachment(conversationId: string, file: unknown, fileName?: string): Promise<SbResult<{ attachment: unknown }>> {\n const form = new FormData();\n form.append('file', file as Blob, fileName);\n\n return this.request(\n 'POST',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/attachments`,\n form\n );\n }\n\n closeConversation(conversationId: string): Promise<SbResult<{ conversation: Conversation }>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/close`);\n }\n\n rateConversation(conversationId: string, rating: number, comment?: string): Promise<SbResult<unknown>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/rate`, {\n rating,\n comment,\n });\n }\n\n // ── Push ──────────────────────────────────────────────────────────────\n\n /**\n * Cihaz token'ını kaydeder. Token'ı almak (FCM/APNs/Web Push izni) ev\n * sahibinin işidir; SDK yalnız iletir — izin diyaloğunu kimin, ne zaman\n * göstereceği ürün kararıdır, kütüphane kararı değil.\n */\n registerDevice(input: RegisterDeviceInput): Promise<SbResult<unknown>> {\n return this.request('POST', '/v1/sdk/devices', input);\n }\n\n /** Çıkışta çağrılır: kayıt silinmez, kapatılır (geçmiş korunur). */\n unregisterDevice(token: string): Promise<SbResult<unknown>> {\n return this.request('DELETE', `/v1/sdk/devices/${enc(token)}`);\n }\n\n /**\n * Bildirime dokunuldu — açılma damgası.\n *\n * Push'ta açılmayı YALNIZCA uygulama bilir: FCM/APNs \"teslim ettim\" der,\n * \"kullanıcı dokundu\" demez. Bildirim yükündeki `data.sb_message_id`\n * değerini buraya geri gönderin.\n *\n * ```ts\n * // React Native / Expo — bildirime dokunma işleyicisinde\n * const id = response.notification.request.content.data?.sb_message_id\n * if (id) await sb.reportPushOpened(String(id))\n * ```\n *\n * Bilinmeyen kimlikte de başarılı döner: uygulamanın yeniden denemesi\n * gereksiz olsun.\n */\n reportPushOpened(messageId: string): Promise<SbResult<unknown>> {\n return this.request('POST', '/v1/sdk/push/opened', { message_id: messageId });\n }\n\n // ── HTTP ──────────────────────────────────────────────────────────────\n\n private async request<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body?: unknown,\n query?: object\n ): Promise<SbResult<T>> {\n const stored = await this.loadVisitor();\n const isForm = typeof FormData !== 'undefined' && body instanceof FormData;\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'X-Signalbird-Key': this.config.publicKey,\n };\n\n /*\n * Kanal başlığı YOLA göre seçilir: cihaz uçları push kanalını, geri kalan\n * her şey sohbet kanalını ister. İstemciye \"hangi başlığı göndereyim\"\n * diye sormak, ilk entegrasyonda kaybedilen yarım saat demekti.\n */\n const moduleKey = path.startsWith('/v1/sdk/devices') || path.startsWith('/v1/sdk/push')\n ? this.config.pushKey\n : this.config.chatKey;\n\n if (moduleKey) headers['X-Signalbird-Module-Key'] = moduleKey;\n\n if (stored?.secret) headers['X-Signalbird-Visitor'] = stored.secret;\n if (body !== undefined && !isForm) headers['Content-Type'] = 'application/json';\n if (this.config.locale) headers['X-Locale'] = this.config.locale;\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await this.doFetch(this.baseUrl + path + buildQuery(query), {\n method,\n headers,\n body: body === undefined ? undefined : isForm ? (body as BodyInit) : JSON.stringify(body),\n signal: controller.signal,\n });\n\n const text = await response.text();\n let data: any = null;\n\n try {\n data = text ? JSON.parse(text) : null;\n } catch {\n data = text;\n }\n\n if (response.ok) {\n return { ok: true, status: response.status, data: data as T };\n }\n\n const code: string =\n (data && typeof data === 'object' && typeof data.code === 'string' && data.code) ||\n (response.status === 422 ? 'VALIDATION_ERROR' : `HTTP_${response.status}`);\n\n // Sır geçersizse yerel kimliği at: bir sonraki çağrı yeni oturum açar.\n // Aksi hâlde ziyaretçi sonsuza kadar 401 alırdı ve sohbet sessizce ölürdü.\n if (code === 'VISITOR_INVALID' || response.status === 401) {\n await this.signOut();\n }\n\n if (this.config.debug) {\n console.warn(`[signalbird] ${code} (HTTP ${response.status})`);\n }\n\n return {\n ok: false,\n status: response.status,\n code,\n message:\n (data && typeof data === 'object' && typeof data.message === 'string' && data.message) ||\n `HTTP ${response.status}`,\n data: data as T,\n };\n } catch (error) {\n const timedOut = error instanceof Error && error.name === 'AbortError';\n\n if (this.config.debug) {\n console.warn('[signalbird] ulaşılamadı:', error);\n }\n\n return {\n ok: false,\n status: 0,\n code: timedOut ? 'TIMEOUT' : 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'network error',\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async loadVisitor(): Promise<StoredVisitor | null> {\n if (this.loaded) return this.visitor;\n\n this.loaded = true;\n\n try {\n const raw = await this.storage.getItem(STORAGE_KEY);\n if (!raw) return null;\n\n const parsed = JSON.parse(raw) as StoredVisitor;\n\n // Anahtar değiştiyse (uygulama döndürüldü, farklı ortam) kimlik geçersizdir.\n if (!parsed?.secret || parsed.publicKey !== this.config.publicKey) return null;\n\n this.visitor = parsed;\n } catch {\n this.visitor = null;\n }\n\n return this.visitor;\n }\n\n private async storeVisitor(visitor: StoredVisitor): Promise<void> {\n this.visitor = visitor;\n this.loaded = true;\n\n try {\n await this.storage.setItem(STORAGE_KEY, JSON.stringify(visitor));\n } catch {\n // Depo yazamıyorsa (kota, gizli sekme) oturum bu sekmede yaşar.\n }\n }\n}\n\nfunction enc(value: string): string {\n return encodeURIComponent(value);\n}\n\nfunction buildQuery(query: object | undefined): string {\n if (!query) return '';\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query as Record<string, unknown>)) {\n if (value === undefined || value === null) continue;\n params.append(key, String(value));\n }\n\n const encoded = params.toString();\n\n return encoded ? `?${encoded}` : '';\n}\n","/**\n * Canlı bağlantı — bağımlılıksız socket.io istemcisi.\n *\n * KARAR 2026-08-29 (Ahmet): \"Chat sistemi hiç durmadan sürekli request atıyor.\n * Bu böyle olmaz, köylü işi bu. WebSocket kurmamız lazım.\"\n *\n * ── NİYE `socket.io-client` DEĞİL ─────────────────────────────────────────\n *\n * Widget'a paket eklenmez (CLAUDE.md kuralı): 20 KB gzip'lik balona 40 KB'lık\n * bir kütüphane koymak, sohbeti açmak için sayfayı yavaşlatmaktır. Sunucu\n * tarafında socket.io var (odalar, yeniden bağlanma, bakım kolaylığı) ama\n * tarayıcı tarafında bize gereken protokol parçası küçük.\n *\n * ── PROTOKOL (Engine.IO v4 + Socket.IO v5) ────────────────────────────────\n *\n * Ham WebSocket üzerinden, metin çerçeveleri:\n *\n * ← `0{\"sid\":…,\"pingInterval\":…}` Engine.IO açılış\n * → `40` ana ad alanına bağlan\n * ← `40{\"sid\":…}` bağlandı — BU `sid` socket.id'dir\n * → `42[\"subscribe\",{…}]` olay\n * ← `42[\"chat.message\",{…}]` sunucu olayı\n * ← `2` / → `3` ping / pong (ping'i SUNUCU atar; biz\n * yalnız cevaplarız — sessiz bağlantıyı\n * canlı tutmak onun işi)\n *\n * `transports: ['websocket']` sunucuda zorunlu tutuluyor, yani uzun yoklamaya\n * (polling) düşme ihtimali yok — zaten kaçtığımız şey o.\n *\n * ── NİYE `src/shared/` ────────────────────────────────────────────────────\n *\n * Widget ve `app` yüzeyi (ChatSession → penyu, React Native) AYNI istemciyi\n * kullanır. İkinci bir nüsha yazmak, yeniden bağlanma merdiveni gibi ince bir\n * mantığı iki ayrı yerde doğru tutmayı gerektirirdi; ilk ayrışmada mobil\n * bağlantı web'de olmayan bir şekilde kopar ve kimse sebebini bulamaz.\n *\n * Sınıfın DOM bağımlılığı yoktur — yalnız `WebSocket` global'i gerekir ve o\n * React Native'de de vardır.\n */\n\nexport interface SocketConfig {\n enabled: boolean;\n /** `https://ws.signalbird.io` — bootstrap yanıtından gelir. */\n url?: string;\n}\n\nexport interface SocketEvent {\n name: string;\n data: Record<string, unknown>;\n}\n\n/** Kanal imzasını API'den alan işlev. */\ntype AuthFn = (socketId: string, channel: string) => Promise<{ auth: string; at: number } | null>;\n\n/** Yeniden bağlanma merdiveni (ms). Sonuncusu tekrarlanır. */\nconst BACKOFF = [1000, 2000, 5000, 10000, 30000];\n\nexport class Socket {\n private ws: WebSocket | null = null;\n private sid: string | null = null;\n private attempt = 0;\n private closed = false;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private pending = new Set<string>();\n private joined = new Set<string>();\n\n constructor(\n private readonly config: SocketConfig,\n private readonly auth: AuthFn,\n private readonly onEvent: (event: SocketEvent) => void,\n private readonly onState: (connected: boolean) => void,\n private readonly log: (...args: unknown[]) => void = () => {},\n ) {}\n\n get connected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN && this.sid !== null;\n }\n\n connect(): void {\n if (!this.config.enabled || !this.config.url) return;\n if (typeof WebSocket === 'undefined') return;\n if (this.ws) return;\n\n this.closed = false;\n\n // `https://…` → `wss://…/socket.io/?EIO=4&transport=websocket`\n const base = this.config.url.replace(/^http/, 'ws').replace(/\\/$/, '');\n const url = `${base}/socket.io/?EIO=4&transport=websocket`;\n\n try {\n this.ws = new WebSocket(url);\n } catch (e) {\n this.log('socket open failed', e);\n this.retry();\n return;\n }\n\n this.ws.onmessage = (ev) => this.handle(String(ev.data));\n this.ws.onclose = () => this.retry();\n this.ws.onerror = () => {\n // `onerror`dan sonra `onclose` da gelir; yeniden bağlanma orada yönetilir\n // ki iki zincir birden kurulmasın.\n this.log('socket error');\n };\n }\n\n /** Kanala abone ol. Bağlantı yoksa kuyruğa alınır, kurulunca gönderilir. */\n subscribe(channel: string): void {\n if (this.joined.has(channel) || this.pending.has(channel)) return;\n\n this.pending.add(channel);\n\n if (this.connected) void this.flush();\n }\n\n close(): void {\n this.closed = true;\n\n if (this.timer) clearTimeout(this.timer);\n\n this.timer = null;\n this.joined.clear();\n\n try {\n this.ws?.close();\n } catch {\n /* yut */\n }\n\n this.ws = null;\n this.sid = null;\n }\n\n // ── Protokol ─────────────────────────────────────────────────────────\n\n private handle(frame: string): void {\n // Engine.IO paket türü ilk karakterdir.\n const type = frame[0];\n\n if (type === '0') {\n // Açılış — asıl kimlik Socket.IO `40` yanıtında gelir.\n this.send('40');\n return;\n }\n\n if (type === '2') {\n this.send('3'); // ping → pong\n return;\n }\n\n if (type !== '4') return; // yalnız MESSAGE paketleri ilgilendiriyor\n\n const sub = frame[1];\n const body = frame.slice(2);\n\n // `40{…}` — ad alanına bağlandık.\n if (sub === '0') {\n try {\n this.sid = String(JSON.parse(body || '{}').sid || '');\n } catch {\n this.sid = '';\n }\n\n this.attempt = 0;\n this.onState(true);\n void this.flush();\n return;\n }\n\n // `42[…]` — sunucu olayı. `43N[…]` (ack) bizi ilgilendirmiyor: abonelik\n // sonucunu zaten bir sonraki yayında görürüz.\n if (sub === '2') {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(body);\n } catch {\n return;\n }\n\n if (!Array.isArray(parsed)) return;\n\n const [name, data] = parsed as [string, Record<string, unknown>];\n\n if (typeof name === 'string' && name.startsWith('chat.')) {\n this.onEvent({ name, data: data ?? {} });\n }\n }\n }\n\n /**\n * Bekleyen kanallar için imza al ve `subscribe` yolla.\n *\n * İmza her BAĞLANTIDA yeniden alınır: `socket_id`e bağlı ve zaman damgalı.\n * Saklamak, ikinci bağlantıda sessizce reddedilmek demekti.\n */\n private async flush(): Promise<void> {\n const sid = this.sid;\n\n if (!sid) return;\n\n for (const channel of Array.from(this.pending)) {\n try {\n const signed = await this.auth(sid, channel);\n\n if (!signed) {\n // Sunucu \"hayır\" dediyse tekrar sormak yalnız istek üretir.\n this.pending.delete(channel);\n continue;\n }\n\n this.emit('subscribe', { channel, auth: signed.auth, at: signed.at });\n this.pending.delete(channel);\n this.joined.add(channel);\n } catch (e) {\n this.log('subscribe failed', channel, e);\n }\n }\n }\n\n /**\n * Olay yolla — ACK İSTEMEDEN.\n *\n * `subscribe`in sonucunu beklemek bir tur daha protokol yönetmek demekti;\n * oysa sonucu zaten davranıştan görüyoruz: imza tutmadıysa yayın gelmez ve\n * polling merdiveni işini yapmaya devam eder.\n */\n private emit(event: string, payload: unknown): void {\n this.send(`42${JSON.stringify([event, payload])}`);\n }\n\n private send(frame: string): void {\n if (this.ws?.readyState !== WebSocket.OPEN) return;\n\n try {\n this.ws.send(frame);\n } catch {\n /* yut */\n }\n }\n\n private retry(): void {\n this.ws = null;\n this.sid = null;\n\n // Kopan bağlantıdaki abonelikler yeni bağlantıda yeniden kurulmalı:\n // imza socket_id'ye bağlı, eskisi geçersiz.\n this.joined.forEach((c) => this.pending.add(c));\n this.joined.clear();\n this.onState(false);\n\n if (this.closed) return;\n\n const delay = BACKOFF[Math.min(this.attempt, BACKOFF.length - 1)];\n this.attempt++;\n\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => this.connect(), delay);\n }\n}\n","/**\n * Sohbet oturumu — çatısız durum yönetimi.\n *\n * `SignalbirdApp` ham uçları verir; burası bir sohbet ekranının gerçekten\n * ihtiyaç duyduğu şeyi verir: mesaj listesi, okunmamış sayısı, yazıyor durumu,\n * iyimser gönderim ve yoklama merdiveni. React/Vue/Angular/React Native\n * uyarlamaları bu sınıfa abone olur — üçünde de aynı mantığı yeniden yazmak,\n * üç ayrı hata takımı üretmek demekti.\n *\n * ── CANLI BAĞLANTI + YOKLAMA ──────────────────────────────────────────────\n *\n * 29 Ağu 2026'ya kadar burada yalnız yoklama vardı ve mobil, widget canlıya\n * geçtikten sonra da saniyede istek atmaya devam etti. Artık aynı soket\n * istemcisi (`../shared/socket`) burada da çalışıyor.\n *\n * YAYIN HABER TAŞIR, VERİ TAŞIMAZ: soketten gelen olay yalnız \"yeni bir şey\n * var\" der; mesajın kendisi HER ZAMAN kendi yetkimizle yeniden çekilir. Aksi\n * hâlde yayın kanalına düşen bir hata, okuma yetkisi olmayan birine mesaj\n * gövdesi göstermeye dönüşürdü.\n *\n * YOKLAMA KALDIRILMAZ, YAVAŞLAR. Bağlantı kurulduğunda panel açıkken 3 s\n * yerine 45 s, kapalıyken merdivenin son basamağı kullanılır: soket düşerse\n * ya da bir olay kaybolursa konuşma yine ilerler. Emniyet ağını sırf gereksiz\n * göründüğü için sökmek, düştüğünüz gün onu aramak demektir.\n *\n * Yoklama merdiveni (penyu deseni): panel açıkken 3 s, kapalıyken 20 s ×3 →\n * 60 s ×2 → 180 s. Yeni veri merdiveni sıfırlar; uygulama arka plandayken tur\n * atlanır.\n */\nimport { clientId, SignalbirdApp } from './client';\nimport { Socket } from '../shared/socket';\nimport type { BootstrapResult, Conversation, Message, SbResult, SessionInput, StartConversationInput, TopicOption } from './types';\n\nexport interface ChatState {\n /** Sohbet bu uygulamada açık mı (`bootstrap` cevabı). */\n enabled: boolean;\n loading: boolean;\n conversation: Conversation | null;\n messages: Message[];\n unread: number;\n agentTyping: boolean;\n withinHours: boolean;\n /**\n * Ziyaretçinin seçebileceği destek konuları (boşsa konu adımı çizilmez).\n * Seçimi `setTopic()` taşır; ilk konuşma açılırken gönderilir.\n */\n topics: TopicOption[];\n /** Seçili konu (slug) — ilk konuşmayla birlikte gider. */\n topic: string | null;\n /** Son hatanın kodu — arayüz isterse gösterir, göstermezse yutar. */\n errorCode?: string;\n /**\n * Uygulamanın sohbet ayarları (renk, logo, tema, puanlama bağlantısı…).\n *\n * Ekran bunları PANELDEN alır, kendi içine gömmez: müşteri rengini ya da\n * puanlama adresini değiştirdiğinde yeni sürüm yayınlamak gerekmesin.\n */\n settings: BootstrapResult['app']['chat'] | null;\n}\n\nexport type ChatListener = (state: ChatState) => void;\n\nexport interface ChatSessionOptions {\n /** Panel açık mı — yoklama hızını belirler. */\n active?: boolean;\n /** Arka plandayken tur atlanır; varsayılan: `document.visibilityState`. */\n isVisible?: () => boolean;\n /** Açılışta oturum kurulurken kullanılacak ziyaretçi bilgisi. */\n visitor?: SessionInput;\n}\n\n/** Kapalı panelde yoklama aralıkları (ms) — son değer sonsuza kadar tekrarlar. */\nconst IDLE_LADDER = [20_000, 20_000, 20_000, 60_000, 60_000, 180_000];\nconst ACTIVE_INTERVAL = 3_000;\n\n/** Soket bağlıyken açık paneldeki yoklama — emniyet ağı, ana kanal değil. */\nconst ACTIVE_LIVE_INTERVAL = 45_000;\n\nexport class ChatSession {\n private state: ChatState = {\n enabled: false,\n loading: true,\n topics: [],\n topic: null,\n conversation: null,\n messages: [],\n unread: 0,\n agentTyping: false,\n withinHours: true,\n settings: null,\n };\n\n private listeners = new Set<ChatListener>();\n private timer: ReturnType<typeof setTimeout> | null = null;\n private step = 0;\n private active: boolean;\n private stopped = false;\n private polling = false;\n private socket: Socket | null = null;\n private live = false;\n /**\n * Bir sonraki `refresh()` İMLEÇSİZ olsun mu.\n *\n * \"Var olan mesaj değişti\" haberi geldiğinde açılır: imleçli çekim\n * (`?after=<son mesaj>`) o mesajı bir daha getirmez, dolayısıyla çeviri ya\n * da düzenleme ekrana hiç yansımaz.\n */\n private forceFull = false;\n\n constructor(\n private readonly app: SignalbirdApp,\n private readonly options: ChatSessionOptions = {}\n ) {\n this.active = options.active ?? false;\n }\n\n // ── Abonelik ──────────────────────────────────────────────────────────\n\n subscribe(listener: ChatListener): () => void {\n this.listeners.add(listener);\n listener(this.state);\n\n return () => this.listeners.delete(listener);\n }\n\n snapshot(): ChatState {\n return this.state;\n }\n\n // ── Yaşam döngüsü ─────────────────────────────────────────────────────\n\n /** Bootstrap + varsa mevcut konuşmayı yükler, sonra yoklamayı başlatır. */\n async start(): Promise<void> {\n this.stopped = false;\n\n const boot = await this.app.bootstrap();\n const app = boot.data?.app;\n\n if (!boot.ok || !app?.chat_enabled) {\n this.patch({ enabled: false, loading: false, errorCode: boot.code });\n\n return;\n }\n\n this.patch({\n enabled: true,\n withinHours: app.within_hours ?? true,\n topics: boot.data?.topics ?? [],\n settings: app.chat ?? null,\n });\n\n this.openSocket(boot.data?.realtime);\n\n // Ziyaretçi yoksa oturum AÇILMAZ: ilk mesaja kadar bekleriz. Her sayfa\n // görüntülemesinde ziyaretçi kaydı açmak, hiç konuşmayacak binlerce boş\n // kayıt üretirdi.\n if (await this.app.currentVisitor()) {\n await this.refresh();\n }\n\n this.patch({ loading: false });\n this.schedule();\n }\n\n /** Panel açıldı/kapandı — yoklama hızı buna göre değişir. */\n setActive(active: boolean): void {\n if (this.active === active) return;\n\n this.active = active;\n this.step = 0;\n\n if (active) {\n // Kapanmış sohbet geri açılmaz: ekran yeniden görünür olduğunda\n // sıfırdan başlar (bkz. `refresh` ve widget'taki aynı kural).\n if (this.state.conversation?.status === 'closed') this.reset();\n\n void this.refresh();\n }\n\n this.schedule();\n }\n\n /**\n * Konuşmayı bırakır; sonraki mesaj YENİ bir konuşma açar.\n *\n * Ekranın \"yeni sohbet\" düğmesi de bunu çağırır. Sunucuda hiçbir şey\n * silinmez — yalnız bu oturumun neye baktığı değişir.\n */\n reset(): void {\n this.patch({ conversation: null, messages: [], unread: 0, agentTyping: false, errorCode: undefined });\n this.step = 0;\n }\n\n stop(): void {\n this.stopped = true;\n\n if (this.timer) clearTimeout(this.timer);\n\n this.timer = null;\n\n this.socket?.close();\n this.socket = null;\n this.live = false;\n }\n\n /** Canlı bağlantı kurulu mu — arayüz isterse gösterir (zorunlu değil). */\n get isLive(): boolean {\n return this.live;\n }\n\n // ── Eylemler ──────────────────────────────────────────────────────────\n\n /** Ön-form gönderildiğinde ya da uygulama kullanıcıyı tanıdığında. */\n async openSession(input: SessionInput): Promise<SbResult<unknown>> {\n const result = await this.app.startSession(input);\n\n if (result.ok) {\n // Kanal adı ziyaretçi kimliğini içerir; kimlik ancak ŞİMDİ doğdu.\n void this.joinVisitorChannel();\n await this.refresh();\n }\n\n return result;\n }\n\n /**\n * Mesaj gönderir. Konuşma yoksa açar.\n *\n * İyimser: mesaj listeye ANINDA düşer, `client_id` ile eşlenir. Sunucu\n * cevabı gelince yerel kopya onunla değiştirilir; başarısızsa `failed`\n * işaretlenir ve arayüz \"yeniden dene\" gösterebilir.\n */\n async send(body: string, attachments?: unknown[]): Promise<SbResult<unknown>> {\n const trimmed = body.trim();\n\n if (!trimmed && !attachments?.length) {\n return { ok: false, status: 0, code: 'EMPTY_BODY', message: 'Mesaj boş.' };\n }\n\n const cid = clientId();\n const optimistic: Message & { failed?: boolean } = {\n id: cid,\n client_id: cid,\n sender_type: 'visitor',\n body: trimmed,\n created_at: new Date().toISOString(),\n };\n\n this.patch({ messages: [...this.state.messages, optimistic] });\n\n // Ziyaretçi yoksa önce oturum: ilk mesaj kimliği de yaratır.\n if (!(await this.app.currentVisitor())) {\n const session = await this.app.startSession(this.options.visitor ?? {});\n\n if (!session.ok) return this.markFailed(cid, session);\n\n void this.joinVisitorChannel();\n }\n\n const conversation = this.state.conversation;\n\n const result = conversation\n ? await this.app.sendMessage(conversation.id, { body: trimmed, client_id: cid, attachments })\n : await this.app.startConversation({\n body: trimmed,\n client_id: cid,\n attachments,\n ...(this.state.topic ? { topic: this.state.topic } : {}),\n } as StartConversationInput);\n\n if (!result.ok) return this.markFailed(cid, result);\n\n await this.refresh();\n this.step = 0;\n this.schedule();\n\n return result;\n }\n\n /**\n * Ziyaretçinin konu seçimi. Konuşma AÇILDIKTAN sonra çağrılırsa etkisizdir:\n * açılmış konuşmanın konusunu ajan panelden değiştirir — ziyaretçiye kendi\n * konuşmasını yeniden sınıflandırma yetkisi vermek, atamayı da bozardı.\n */\n setTopic(slug: string | null): void {\n this.patch({ topic: slug });\n }\n\n /** İlk tuşta `true`, 2.5 s hareketsizlikte `false` — çağıran zamanlar. */\n typing(isTyping: boolean): void {\n const conversation = this.state.conversation;\n\n if (!conversation) return;\n\n void this.app.setTyping(conversation.id, isTyping);\n }\n\n /** Görülen son mesaja kadar okundu işaretler. */\n async markRead(): Promise<void> {\n const conversation = this.state.conversation;\n const last = this.state.messages[this.state.messages.length - 1];\n\n if (!conversation || !last) return;\n\n await this.app.markRead(conversation.id, last.id);\n this.patch({ unread: 0 });\n }\n\n async close(rating?: number, comment?: string): Promise<void> {\n const conversation = this.state.conversation;\n\n if (!conversation) return;\n\n if (typeof rating === 'number') {\n await this.app.rateConversation(conversation.id, rating, comment);\n }\n\n await this.app.closeConversation(conversation.id);\n await this.refresh();\n }\n\n /** Sunucudaki durumu çeker; imleç varsa yalnız yenileri ister. */\n async refresh(): Promise<void> {\n const current = this.state.conversation;\n\n if (!current) {\n const list = await this.app.listConversations();\n\n /*\n * YALNIZ AÇIK KONUŞMA BENİMSENİR (29 Ağu 2026).\n *\n * Eskiden listenin ilk kaydı alınıyordu ve o kayıt kapanmış olabilirdi:\n * ziyaretçi sohbeti bitirip ekranı yeniden açtığında, okunabilen ama\n * yazılamayan eski yazışma geri geliyordu. `closed` sunucuda da\n * ziyaretçi için finaldir; açık konuşma yoksa doğru cevap \"konuşma\n * yok\"tur ve ekran sıfırdan başlar.\n *\n * `resolved` bunun DIŞINDA: onu ajan işaretler, ziyaretçi hâlâ yazar.\n */\n const first = (list.data?.data ?? []).find((c) => c.status !== 'closed');\n\n if (!first) {\n this.patch({ errorCode: list.ok ? undefined : list.code });\n\n return;\n }\n\n const detail = await this.app.getConversation(first.id);\n\n this.applyConversation(detail.data?.conversation ?? first, true);\n\n return;\n }\n\n // `forceFull` açıksa imleç atlanır: değişen mesaj zaten imlecin\n // gerisinde kaldığı için `after` ile hiç dönmez.\n const after = this.forceFull ? undefined : this.lastServerMessageId();\n\n this.forceFull = false;\n\n const detail = await this.app.getConversation(current.id, after ? { after } : undefined);\n\n if (!detail.ok || !detail.data?.conversation) {\n this.patch({ errorCode: detail.code });\n\n return;\n }\n\n this.applyConversation(detail.data.conversation, !after);\n }\n\n // ── İç işler ──────────────────────────────────────────────────────────\n\n private applyConversation(conversation: Conversation, replace: boolean): void {\n const incoming = conversation.messages ?? [];\n const merged = replace ? incoming : mergeMessages(this.state.messages, incoming);\n\n // Yeni veri geldiyse merdiven sıfırlanır: konuşma canlandığında bir sonraki\n // yoklamayı üç dakika beklemek, kullanıcıyı terk edilmiş hissettirir.\n if (incoming.length) this.step = 0;\n\n this.patch({\n conversation,\n messages: merged,\n unread: conversation.unread_count ?? 0,\n agentTyping: !!conversation.agent_typing,\n withinHours: conversation.within_hours ?? this.state.withinHours,\n errorCode: undefined,\n });\n }\n\n /** İyimser kayıtlar sunucu kimliği taşımaz; imleç yalnız gerçek kimliktir. */\n private lastServerMessageId(): string | undefined {\n for (let i = this.state.messages.length - 1; i >= 0; i--) {\n const message = this.state.messages[i];\n\n if (message.id && !message.id.startsWith('c_') && message.id !== message.client_id) {\n return message.id;\n }\n }\n\n return undefined;\n }\n\n private markFailed(cid: string, result: SbResult<unknown>): SbResult<unknown> {\n this.patch({\n messages: this.state.messages.map((m) =>\n m.client_id === cid ? { ...m, failed: true } : m\n ) as Message[],\n errorCode: result.code,\n });\n\n return result;\n }\n\n // ── Canlı bağlantı ────────────────────────────────────────────────────\n\n /**\n * Ziyaretçinin kendi kanalına bağlanır (`visitor.<id>`).\n *\n * Kanal ziyaretçi kimliği kurulduktan SONRA bilinir; ilk mesajla kimlik\n * doğduğunda `refresh()` üzerinden yeniden denenir. Bağlantı kurulamazsa\n * hiçbir şey olmaz: yoklama zaten çalışıyor.\n */\n private openSocket(realtime?: { enabled: boolean; url?: string }): void {\n if (!realtime?.enabled || !realtime.url || this.socket) return;\n\n this.socket = new Socket(\n realtime,\n async (socketId, channel) => {\n const result = await this.app.socketAuth(socketId, channel);\n\n return result.ok && result.data ? result.data : null;\n },\n (event) => {\n // OLAYIN İÇİNDEKİ VERİ KULLANILMAZ, yalnız \"bir şey oldu\" bilgisi:\n // mesajı kendi yetkimizle çekeriz. Tek istisna `updated` işareti —\n // o, verinin kendisi değil, NASIL çekileceğinin talimatıdır.\n if (event.data.updated === true) this.forceFull = true;\n\n this.step = 0;\n void this.refresh();\n },\n (connected) => {\n this.live = connected;\n this.schedule();\n },\n );\n\n this.socket.connect();\n void this.joinVisitorChannel();\n }\n\n /** Ziyaretçi kimliği varsa kendi kanalına katılır; yoksa sessizce döner. */\n private async joinVisitorChannel(): Promise<void> {\n const visitor = await this.app.currentVisitor();\n\n if (visitor?.id) this.socket?.subscribe(`visitor.${visitor.id}`);\n }\n\n private schedule(): void {\n if (this.timer) clearTimeout(this.timer);\n if (this.stopped) return;\n\n /*\n * Soket bağlıysa yoklama YAVAŞLAR, DURMAZ. Açık panelde 3 s yerine 45 s;\n * kapalı panelde merdivenin son basamağı — bir olay kaybolsa bile\n * konuşma en geç bu kadar gecikir.\n */\n const delay = this.active\n ? (this.live ? ACTIVE_LIVE_INTERVAL : ACTIVE_INTERVAL)\n : this.live\n ? IDLE_LADDER[IDLE_LADDER.length - 1]\n : IDLE_LADDER[Math.min(this.step, IDLE_LADDER.length - 1)];\n\n this.timer = setTimeout(() => void this.tick(), delay);\n }\n\n private async tick(): Promise<void> {\n if (this.stopped || this.polling) return;\n\n // Arka plandaki sekme/uygulama tur atlar: görünmeyen sohbet için ağ\n // trafiği üretmek pil ve kota harcar.\n if (!this.visible()) {\n this.schedule();\n\n return;\n }\n\n this.polling = true;\n\n try {\n await this.refresh();\n } finally {\n this.polling = false;\n }\n\n if (!this.active) this.step++;\n\n this.schedule();\n }\n\n private visible(): boolean {\n if (this.options.isVisible) return this.options.isVisible();\n\n try {\n if (typeof document !== 'undefined' && document.visibilityState) {\n return document.visibilityState === 'visible';\n }\n } catch {\n /* yok say */\n }\n\n return true;\n }\n\n private patch(partial: Partial<ChatState>): void {\n this.state = { ...this.state, ...partial };\n\n for (const listener of this.listeners) {\n try {\n listener(this.state);\n } catch (error) {\n // Bir dinleyicinin hatası diğerlerini ve oturumu düşürmemeli.\n console.warn('[signalbird] dinleyici hatası:', error);\n }\n }\n }\n}\n\n/** Sunucu kaydı, aynı `client_id`'li yerel kopyanın yerine geçer. */\nfunction mergeMessages(existing: Message[], incoming: Message[]): Message[] {\n if (!incoming.length) return existing;\n\n const byKey = new Map<string, Message>();\n\n for (const message of existing) {\n byKey.set(message.client_id ?? message.id, message);\n }\n\n for (const message of incoming) {\n const key = message.client_id ?? message.id;\n byKey.delete(key);\n byKey.set(key, message);\n }\n\n return [...byKey.values()].sort((a, b) => (a.created_at ?? '').localeCompare(b.created_at ?? ''));\n}\n","/**\n * `signalbird/angular` — Angular servisi ve sağlayıcısı.\n *\n * Dekoratör KULLANMAZ: `@Injectable()` yazsaydık paketin derlenmesi Angular\n * sürümüne bağlanırdı ve her büyük sürümde yeniden yayın gerekirdi. Bunun\n * yerine düz sınıf + `provideSignalbird()` fabrikası veriyoruz; Angular'ın DI'ı\n * bunu sorunsuz kabul eder ve sürümden bağımsızdır.\n *\n * RxJS bir `peerDependency`'dir (Angular zaten getirir).\n */\nimport { BehaviorSubject, type Observable } from 'rxjs';\nimport { ChatSession, SignalbirdApp } from '../app';\nimport type { AppConfig, ChatState, IdentifyInput, RegisterDeviceInput, SessionInput } from '../app';\n\n/** DI belirteci — Angular'ın `InjectionToken`'ına sarılır (aşağıda). */\nexport const SIGNALBIRD_CONFIG = 'SIGNALBIRD_CONFIG';\n\n/**\n * Uygulama başına tek örnek (`providedIn: 'root'` karşılığı).\n *\n * Sohbet durumu bir `Observable`'dır; şablon `| async` ile doğrudan bağlanır.\n */\nexport class SignalbirdService {\n readonly client: SignalbirdApp;\n\n private readonly session: ChatSession;\n private readonly subject: BehaviorSubject<ChatState>;\n private started = false;\n\n constructor(config: AppConfig) {\n this.client = new SignalbirdApp(config);\n this.session = new ChatSession(this.client, { active: false });\n this.subject = new BehaviorSubject<ChatState>(this.session.snapshot());\n\n this.session.subscribe((state) => this.subject.next(state));\n }\n\n /** Sohbet durumu akışı. İlk abone olduğunda oturum başlar. */\n chat$(): Observable<ChatState> {\n if (!this.started) {\n this.started = true;\n void this.session.start();\n }\n\n return this.subject.asObservable();\n }\n\n /** Panel açık mı — yoklama hızını belirler. */\n setOpen(open: boolean): void {\n this.session.setActive(open);\n }\n\n send(body: string, attachments?: unknown[]): Promise<unknown> {\n return this.session.send(body, attachments);\n }\n\n typing(isTyping: boolean): void {\n this.session.typing(isTyping);\n }\n\n markRead(): Promise<void> {\n return this.session.markRead();\n }\n\n closeConversation(rating?: number, comment?: string): Promise<void> {\n return this.session.close(rating, comment);\n }\n\n openSession(input: SessionInput): Promise<unknown> {\n return this.session.openSession(input);\n }\n\n /**\n * Konuşmayı bırakır; sonraki mesaj YENİ bir konuşma açar (29 Ağu 2026).\n * Kapanmış sohbet geri açılmadığı için arayüzün \"yeni sohbet\" düğmesine\n * bağlanacak bir eyleme ihtiyacı var.\n */\n resetConversation(): void {\n this.session.reset();\n }\n\n identify(input: IdentifyInput): Promise<unknown> {\n return this.client.identify(input);\n }\n\n registerDevice(input: RegisterDeviceInput): Promise<unknown> {\n return this.client.registerDevice(input);\n }\n\n /** Uygulama kapanırken ya da testte: yoklamayı durdurur. */\n destroy(): void {\n this.session.stop();\n this.subject.complete();\n }\n}\n\n/**\n * `bootstrapApplication(App, { providers: [provideSignalbird({ publicKey })] })`\n *\n * Dönen nesne Angular'ın `Provider` biçimindedir ama tipi buraya gömülmez —\n * paket Angular'a derleme zamanı bağımlılık taşımaz.\n */\nexport function provideSignalbird(config: AppConfig): {\n provide: typeof SignalbirdService;\n useFactory: () => SignalbirdService;\n} {\n return {\n provide: SignalbirdService,\n useFactory: () => new SignalbirdService(config),\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/app/client.ts","../src/shared/socket.ts","../src/app/session.ts","../src/angular/index.ts"],"names":["detail","BehaviorSubject"],"mappings":"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","file":"angular.js","sourcesContent":["/**\n * Uygulama istemcisi — son kullanıcı tarafı (sohbet + push kaydı).\n *\n * Tek bir sınıf; tarayıcı, React Native, Electron ve test aynı gövdeyi kullanır.\n * Platform farkı iki noktada toplanmıştır ve ikisi de dışarıdan verilir:\n * `storage` (ziyaretçi sırrı nerede durur) ve `fetchImpl`. Çatıya özel sarmalayıcı\n * yazmak yerine bunu seçtik — React, Vue, Angular ve RN uyarlamaları bu sınıfın\n * ÜSTÜNE oturur, kopyası değildir.\n *\n * Kimlik iki parçadır: açık domain anahtarı (`X-Signalbird-Key`) ve\n * ziyaretçi sırrı (`X-Signalbird-Visitor`). Sır yalnız oturum açılışında döner;\n * kaybolursa yeni oturum açılır ve geçmiş konuşmalar görünmez — bu yüzden\n * saklama katmanı zorunludur, isteğe bağlı değil.\n *\n * Hiçbir metot istisna fırlatmaz: sohbet balonunun hatası müşterinin ödeme\n * sayfasını çökertmemeli. Sonuç her zaman `{ok, status, …}` zarfıdır.\n *\n * Sözleşme: docs/CONTRACT.md § 11\n */\nimport type {\n AppConfig,\n AppStorage,\n BootstrapResult,\n Conversation,\n ConversationQuery,\n IdentifyInput,\n Message,\n RegisterDeviceInput,\n SbResult,\n SendMessageInput,\n SessionInput,\n StartConversationInput,\n Visitor,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://live.signalbird.io/api';\nconst STORAGE_KEY = 'sb_visitor';\n\ninterface StoredVisitor {\n id: string;\n secret: string;\n publicKey: string;\n name?: string | null;\n email?: string | null;\n}\n\n/** Depo verilmezse: tarayıcıda localStorage, başka yerde bellek. */\nfunction defaultStorage(): AppStorage {\n try {\n if (typeof localStorage !== 'undefined') {\n return {\n getItem: (k) => localStorage.getItem(k),\n setItem: (k, v) => localStorage.setItem(k, v),\n removeItem: (k) => localStorage.removeItem(k),\n };\n }\n } catch {\n // Gizli sekme / kısıtlı iframe — belleğe düş.\n }\n\n const memory = new Map<string, string>();\n\n return {\n getItem: (k) => memory.get(k) ?? null,\n setItem: (k, v) => void memory.set(k, v),\n removeItem: (k) => void memory.delete(k),\n };\n}\n\n/** RFC 4122 uyumlu olmak zorunda değil; tek işi yerel kopyayı eşlemek. */\nexport function clientId(): string {\n try {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n } catch {\n /* yok say */\n }\n\n return `c_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport class SignalbirdApp {\n private readonly baseUrl: string;\n private readonly storage: AppStorage;\n private readonly timeout: number;\n private readonly doFetch: typeof fetch;\n private visitor: StoredVisitor | null = null;\n private loaded = false;\n\n constructor(private readonly config: AppConfig) {\n if (!config?.publicKey) {\n throw new Error('Signalbird: publicKey zorunlu (sb_public_live_…).');\n }\n\n // Takım anahtarı istemciye gömülürse tüm gönderim yetkisi sızar. Sunucu da\n // reddederdi ama o noktada anahtar çoktan yayınlanmış olurdu.\n if (!config.publicKey.startsWith('sb_public_live_')) {\n throw new Error(\n 'Signalbird: uygulama istemcisi açık domain anahtarı ister (sb_public_live_…). ' +\n 'Takım anahtarını (sb_…) istemci koduna KOYMAYIN.'\n );\n }\n\n this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.storage = config.storage ?? defaultStorage();\n this.timeout = config.timeout ?? 10000;\n this.doFetch = config.fetchImpl ?? ((...args) => fetch(...args));\n }\n\n // ── Kimlik ────────────────────────────────────────────────────────────\n\n /** Uygulama ayarları: sohbet açık mı, renk, çalışma saati, ön-form. */\n bootstrap(): Promise<SbResult<BootstrapResult>> {\n return this.request('POST', '/v1/sdk/bootstrap', { locale: this.config.locale });\n }\n\n /**\n * Canlı bağlantı kanalı için imza.\n *\n * Ziyaretçinin oturumu yoktur; hangi kanalı dinleyebileceğine SUNUCU karar\n * verir ve yalnız kendi `visitor.<id>` kanalını imzalar. Soket servisi\n * kimseyi tanımaz, yalnız imzayı doğrular.\n */\n socketAuth(socketId: string, channel: string): Promise<SbResult<{ auth: string; at: number }>> {\n return this.request('POST', '/v1/sdk/chat/socket/auth', { socket_id: socketId, channel });\n }\n\n /**\n * Ziyaretçi oturumu açar ya da mevcut olanı günceller.\n *\n * Sır saklanır; ikinci çağrı aynı ziyaretçiyi tazeler. Sunucu `VISITOR_INVALID`\n * derse yerel kimlik silinir ve bir sonraki çağrı yeni oturum açar.\n */\n async startSession(input: SessionInput = {}): Promise<SbResult<{ visitor: Visitor }>> {\n const result = await this.request<{ visitor: Visitor }>('POST', '/v1/sdk/chat/session', input);\n\n const visitor = result.data?.visitor;\n\n if (result.ok && visitor?.id && visitor.secret) {\n await this.storeVisitor({\n id: visitor.id,\n secret: visitor.secret,\n publicKey: this.config.publicKey,\n name: visitor.name ?? null,\n email: visitor.email ?? null,\n });\n }\n\n return result;\n }\n\n /** Oturum açmış kullanıcıyı ziyaretçiye bağlar (kişi kaydı upsert edilir). */\n identify(input: IdentifyInput): Promise<SbResult<{ visitor: Visitor }>> {\n return this.request('POST', '/v1/sdk/identify', input);\n }\n\n /** Saklanan ziyaretçi kimliği — yoksa `null`. */\n async currentVisitor(): Promise<{ id: string; name?: string | null; email?: string | null } | null> {\n const stored = await this.loadVisitor();\n\n return stored ? { id: stored.id, name: stored.name, email: stored.email } : null;\n }\n\n /** Yerel kimliği siler: çıkış yapıldığında çağrılır. Sunucudaki kayıt kalır. */\n async signOut(): Promise<void> {\n this.visitor = null;\n this.loaded = true;\n await this.storage.removeItem(STORAGE_KEY);\n }\n\n // ── Sohbet ────────────────────────────────────────────────────────────\n\n listConversations(): Promise<SbResult<{ data: Conversation[] }>> {\n return this.request('GET', '/v1/sdk/chat/conversations');\n }\n\n getConversation(id: string, query?: ConversationQuery): Promise<SbResult<{ conversation: Conversation }>> {\n return this.request('GET', `/v1/sdk/chat/conversations/${enc(id)}`, undefined, query);\n }\n\n /**\n * İlk mesajla konuşma açar. Kota burada harcanır — konuşma başına sayılır,\n * mesaj başına değil.\n */\n startConversation(input: StartConversationInput): Promise<SbResult<{ conversation: Conversation; message: Message }>> {\n return this.request('POST', '/v1/sdk/chat/conversations', {\n client_id: clientId(),\n ...input,\n });\n }\n\n sendMessage(conversationId: string, input: SendMessageInput): Promise<SbResult<{ message: Message }>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/messages`, {\n client_id: clientId(),\n ...input,\n });\n }\n\n /** Yalnız kendi mesajı ve gönderimden sonraki 15 dakika içinde. */\n editMessage(conversationId: string, messageId: string, body: string): Promise<SbResult<{ message: Message }>> {\n return this.request(\n 'PATCH',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/messages/${enc(messageId)}`,\n { body }\n );\n }\n\n deleteMessage(conversationId: string, messageId: string): Promise<SbResult<unknown>> {\n return this.request(\n 'DELETE',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/messages/${enc(messageId)}`\n );\n }\n\n /** Aynı emoji ikinci kez gönderilirse tepki kaldırılır. */\n reactToMessage(conversationId: string, messageId: string, emoji: string): Promise<SbResult<{ message: Message }>> {\n return this.request(\n 'POST',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/messages/${enc(messageId)}/reactions`,\n { emoji }\n );\n }\n\n setTyping(conversationId: string, isTyping: boolean): Promise<SbResult<unknown>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/typing`, {\n is_typing: isTyping,\n });\n }\n\n markRead(conversationId: string, lastMessageId?: string): Promise<SbResult<unknown>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/read`, {\n last_message_id: lastMessageId,\n });\n }\n\n /**\n * Ek dosya yükler; dönen tanımlayıcı `sendMessage`'a `attachments` içinde\n * verilir. İki adım olmasının sebebi: dosya yüklenirken mesaj metni hâlâ\n * yazılıyor olabilir ve yarım kalan yükleme mesaj kaydı yaratmamalı.\n */\n uploadAttachment(conversationId: string, file: unknown, fileName?: string): Promise<SbResult<{ attachment: unknown }>> {\n const form = new FormData();\n form.append('file', file as Blob, fileName);\n\n return this.request(\n 'POST',\n `/v1/sdk/chat/conversations/${enc(conversationId)}/attachments`,\n form\n );\n }\n\n closeConversation(conversationId: string): Promise<SbResult<{ conversation: Conversation }>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/close`);\n }\n\n rateConversation(conversationId: string, rating: number, comment?: string): Promise<SbResult<unknown>> {\n return this.request('POST', `/v1/sdk/chat/conversations/${enc(conversationId)}/rate`, {\n rating,\n comment,\n });\n }\n\n // ── Push ──────────────────────────────────────────────────────────────\n\n /**\n * Cihaz token'ını kaydeder. Token'ı almak (FCM/APNs/Web Push izni) ev\n * sahibinin işidir; SDK yalnız iletir — izin diyaloğunu kimin, ne zaman\n * göstereceği ürün kararıdır, kütüphane kararı değil.\n */\n registerDevice(input: RegisterDeviceInput): Promise<SbResult<unknown>> {\n return this.request('POST', '/v1/sdk/devices', input);\n }\n\n /** Çıkışta çağrılır: kayıt silinmez, kapatılır (geçmiş korunur). */\n unregisterDevice(token: string): Promise<SbResult<unknown>> {\n return this.request('DELETE', `/v1/sdk/devices/${enc(token)}`);\n }\n\n /**\n * Bildirime dokunuldu — açılma damgası.\n *\n * Push'ta açılmayı YALNIZCA uygulama bilir: FCM/APNs \"teslim ettim\" der,\n * \"kullanıcı dokundu\" demez. Bildirim yükündeki `data.sb_message_id`\n * değerini buraya geri gönderin.\n *\n * ```ts\n * // React Native / Expo — bildirime dokunma işleyicisinde\n * const id = response.notification.request.content.data?.sb_message_id\n * if (id) await sb.reportPushOpened(String(id))\n * ```\n *\n * Bilinmeyen kimlikte de başarılı döner: uygulamanın yeniden denemesi\n * gereksiz olsun.\n */\n reportPushOpened(messageId: string): Promise<SbResult<unknown>> {\n return this.request('POST', '/v1/sdk/push/opened', { message_id: messageId });\n }\n\n // ── HTTP ──────────────────────────────────────────────────────────────\n\n private async request<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body?: unknown,\n query?: object\n ): Promise<SbResult<T>> {\n const stored = await this.loadVisitor();\n const isForm = typeof FormData !== 'undefined' && body instanceof FormData;\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'X-Signalbird-Key': this.config.publicKey,\n };\n\n /*\n * Kanal başlığı YOLA göre seçilir: cihaz uçları push kanalını, geri kalan\n * her şey sohbet kanalını ister. İstemciye \"hangi başlığı göndereyim\"\n * diye sormak, ilk entegrasyonda kaybedilen yarım saat demekti.\n */\n const moduleKey = path.startsWith('/v1/sdk/devices') || path.startsWith('/v1/sdk/push')\n ? this.config.pushKey\n : this.config.chatKey;\n\n if (moduleKey) headers['X-Signalbird-Module-Key'] = moduleKey;\n\n if (stored?.secret) headers['X-Signalbird-Visitor'] = stored.secret;\n if (body !== undefined && !isForm) headers['Content-Type'] = 'application/json';\n if (this.config.locale) headers['X-Locale'] = this.config.locale;\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await this.doFetch(this.baseUrl + path + buildQuery(query), {\n method,\n headers,\n body: body === undefined ? undefined : isForm ? (body as BodyInit) : JSON.stringify(body),\n signal: controller.signal,\n });\n\n const text = await response.text();\n let data: any = null;\n\n try {\n data = text ? JSON.parse(text) : null;\n } catch {\n data = text;\n }\n\n if (response.ok) {\n return { ok: true, status: response.status, data: data as T };\n }\n\n const code: string =\n (data && typeof data === 'object' && typeof data.code === 'string' && data.code) ||\n (response.status === 422 ? 'VALIDATION_ERROR' : `HTTP_${response.status}`);\n\n // Sır geçersizse yerel kimliği at: bir sonraki çağrı yeni oturum açar.\n // Aksi hâlde ziyaretçi sonsuza kadar 401 alırdı ve sohbet sessizce ölürdü.\n if (code === 'VISITOR_INVALID' || response.status === 401) {\n await this.signOut();\n }\n\n if (this.config.debug) {\n console.warn(`[signalbird] ${code} (HTTP ${response.status})`);\n }\n\n return {\n ok: false,\n status: response.status,\n code,\n message:\n (data && typeof data === 'object' && typeof data.message === 'string' && data.message) ||\n `HTTP ${response.status}`,\n data: data as T,\n };\n } catch (error) {\n const timedOut = error instanceof Error && error.name === 'AbortError';\n\n if (this.config.debug) {\n console.warn('[signalbird] ulaşılamadı:', error);\n }\n\n return {\n ok: false,\n status: 0,\n code: timedOut ? 'TIMEOUT' : 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'network error',\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async loadVisitor(): Promise<StoredVisitor | null> {\n if (this.loaded) return this.visitor;\n\n this.loaded = true;\n\n try {\n const raw = await this.storage.getItem(STORAGE_KEY);\n if (!raw) return null;\n\n const parsed = JSON.parse(raw) as StoredVisitor;\n\n // Anahtar değiştiyse (uygulama döndürüldü, farklı ortam) kimlik geçersizdir.\n if (!parsed?.secret || parsed.publicKey !== this.config.publicKey) return null;\n\n this.visitor = parsed;\n } catch {\n this.visitor = null;\n }\n\n return this.visitor;\n }\n\n private async storeVisitor(visitor: StoredVisitor): Promise<void> {\n this.visitor = visitor;\n this.loaded = true;\n\n try {\n await this.storage.setItem(STORAGE_KEY, JSON.stringify(visitor));\n } catch {\n // Depo yazamıyorsa (kota, gizli sekme) oturum bu sekmede yaşar.\n }\n }\n}\n\nfunction enc(value: string): string {\n return encodeURIComponent(value);\n}\n\nfunction buildQuery(query: object | undefined): string {\n if (!query) return '';\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query as Record<string, unknown>)) {\n if (value === undefined || value === null) continue;\n params.append(key, String(value));\n }\n\n const encoded = params.toString();\n\n return encoded ? `?${encoded}` : '';\n}\n","/**\n * Canlı bağlantı — bağımlılıksız socket.io istemcisi.\n *\n * KARAR 2026-08-29 (Ahmet): \"Chat sistemi hiç durmadan sürekli request atıyor.\n * Bu böyle olmaz, köylü işi bu. WebSocket kurmamız lazım.\"\n *\n * ── NİYE `socket.io-client` DEĞİL ─────────────────────────────────────────\n *\n * Widget'a paket eklenmez (CLAUDE.md kuralı): 20 KB gzip'lik balona 40 KB'lık\n * bir kütüphane koymak, sohbeti açmak için sayfayı yavaşlatmaktır. Sunucu\n * tarafında socket.io var (odalar, yeniden bağlanma, bakım kolaylığı) ama\n * tarayıcı tarafında bize gereken protokol parçası küçük.\n *\n * ── PROTOKOL (Engine.IO v4 + Socket.IO v5) ────────────────────────────────\n *\n * Ham WebSocket üzerinden, metin çerçeveleri:\n *\n * ← `0{\"sid\":…,\"pingInterval\":…}` Engine.IO açılış\n * → `40` ana ad alanına bağlan\n * ← `40{\"sid\":…}` bağlandı — BU `sid` socket.id'dir\n * → `42[\"subscribe\",{…}]` olay\n * ← `42[\"chat.message\",{…}]` sunucu olayı\n * ← `2` / → `3` ping / pong (ping'i SUNUCU atar; biz\n * yalnız cevaplarız — sessiz bağlantıyı\n * canlı tutmak onun işi)\n *\n * `transports: ['websocket']` sunucuda zorunlu tutuluyor, yani uzun yoklamaya\n * (polling) düşme ihtimali yok — zaten kaçtığımız şey o.\n *\n * ── NİYE `src/shared/` ────────────────────────────────────────────────────\n *\n * Widget ve `app` yüzeyi (ChatSession → penyu, React Native) AYNI istemciyi\n * kullanır. İkinci bir nüsha yazmak, yeniden bağlanma merdiveni gibi ince bir\n * mantığı iki ayrı yerde doğru tutmayı gerektirirdi; ilk ayrışmada mobil\n * bağlantı web'de olmayan bir şekilde kopar ve kimse sebebini bulamaz.\n *\n * Sınıfın DOM bağımlılığı yoktur — yalnız `WebSocket` global'i gerekir ve o\n * React Native'de de vardır.\n */\n\nexport interface SocketConfig {\n enabled: boolean;\n /** `https://ws.signalbird.io` — bootstrap yanıtından gelir. */\n url?: string;\n}\n\nexport interface SocketEvent {\n name: string;\n data: Record<string, unknown>;\n}\n\n/** Kanal imzasını API'den alan işlev. */\ntype AuthFn = (socketId: string, channel: string) => Promise<{ auth: string; at: number } | null>;\n\n/** Yeniden bağlanma merdiveni (ms). Sonuncusu tekrarlanır. */\nconst BACKOFF = [1000, 2000, 5000, 10000, 30000];\n\nexport class Socket {\n private ws: WebSocket | null = null;\n private sid: string | null = null;\n private attempt = 0;\n private closed = false;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private pending = new Set<string>();\n private joined = new Set<string>();\n\n constructor(\n private readonly config: SocketConfig,\n private readonly auth: AuthFn,\n private readonly onEvent: (event: SocketEvent) => void,\n private readonly onState: (connected: boolean) => void,\n private readonly log: (...args: unknown[]) => void = () => {},\n ) {}\n\n get connected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN && this.sid !== null;\n }\n\n connect(): void {\n if (!this.config.enabled || !this.config.url) return;\n if (typeof WebSocket === 'undefined') return;\n if (this.ws) return;\n\n this.closed = false;\n\n // `https://…` → `wss://…/socket.io/?EIO=4&transport=websocket`\n const base = this.config.url.replace(/^http/, 'ws').replace(/\\/$/, '');\n const url = `${base}/socket.io/?EIO=4&transport=websocket`;\n\n try {\n this.ws = new WebSocket(url);\n } catch (e) {\n this.log('socket open failed', e);\n this.retry();\n return;\n }\n\n this.ws.onmessage = (ev) => this.handle(String(ev.data));\n this.ws.onclose = () => this.retry();\n this.ws.onerror = () => {\n // `onerror`dan sonra `onclose` da gelir; yeniden bağlanma orada yönetilir\n // ki iki zincir birden kurulmasın.\n this.log('socket error');\n };\n }\n\n /** Kanala abone ol. Bağlantı yoksa kuyruğa alınır, kurulunca gönderilir. */\n subscribe(channel: string): void {\n if (this.joined.has(channel) || this.pending.has(channel)) return;\n\n this.pending.add(channel);\n\n if (this.connected) void this.flush();\n }\n\n close(): void {\n this.closed = true;\n\n if (this.timer) clearTimeout(this.timer);\n\n this.timer = null;\n this.joined.clear();\n\n try {\n this.ws?.close();\n } catch {\n /* yut */\n }\n\n this.ws = null;\n this.sid = null;\n }\n\n // ── Protokol ─────────────────────────────────────────────────────────\n\n private handle(frame: string): void {\n // Engine.IO paket türü ilk karakterdir.\n const type = frame[0];\n\n if (type === '0') {\n // Açılış — asıl kimlik Socket.IO `40` yanıtında gelir.\n this.send('40');\n return;\n }\n\n if (type === '2') {\n this.send('3'); // ping → pong\n return;\n }\n\n if (type !== '4') return; // yalnız MESSAGE paketleri ilgilendiriyor\n\n const sub = frame[1];\n const body = frame.slice(2);\n\n // `40{…}` — ad alanına bağlandık.\n if (sub === '0') {\n try {\n this.sid = String(JSON.parse(body || '{}').sid || '');\n } catch {\n this.sid = '';\n }\n\n this.attempt = 0;\n this.onState(true);\n void this.flush();\n return;\n }\n\n // `42[…]` — sunucu olayı. `43N[…]` (ack) bizi ilgilendirmiyor: abonelik\n // sonucunu zaten bir sonraki yayında görürüz.\n if (sub === '2') {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(body);\n } catch {\n return;\n }\n\n if (!Array.isArray(parsed)) return;\n\n const [name, data] = parsed as [string, Record<string, unknown>];\n\n if (typeof name === 'string' && name.startsWith('chat.')) {\n this.onEvent({ name, data: data ?? {} });\n }\n }\n }\n\n /**\n * Bekleyen kanallar için imza al ve `subscribe` yolla.\n *\n * İmza her BAĞLANTIDA yeniden alınır: `socket_id`e bağlı ve zaman damgalı.\n * Saklamak, ikinci bağlantıda sessizce reddedilmek demekti.\n */\n private async flush(): Promise<void> {\n const sid = this.sid;\n\n if (!sid) return;\n\n for (const channel of Array.from(this.pending)) {\n try {\n const signed = await this.auth(sid, channel);\n\n if (!signed) {\n // Sunucu \"hayır\" dediyse tekrar sormak yalnız istek üretir.\n this.pending.delete(channel);\n continue;\n }\n\n this.emit('subscribe', { channel, auth: signed.auth, at: signed.at });\n this.pending.delete(channel);\n this.joined.add(channel);\n } catch (e) {\n this.log('subscribe failed', channel, e);\n }\n }\n }\n\n /**\n * Olay yolla — ACK İSTEMEDEN.\n *\n * `subscribe`in sonucunu beklemek bir tur daha protokol yönetmek demekti;\n * oysa sonucu zaten davranıştan görüyoruz: imza tutmadıysa yayın gelmez ve\n * polling merdiveni işini yapmaya devam eder.\n */\n private emit(event: string, payload: unknown): void {\n this.send(`42${JSON.stringify([event, payload])}`);\n }\n\n private send(frame: string): void {\n if (this.ws?.readyState !== WebSocket.OPEN) return;\n\n try {\n this.ws.send(frame);\n } catch {\n /* yut */\n }\n }\n\n private retry(): void {\n this.ws = null;\n this.sid = null;\n\n // Kopan bağlantıdaki abonelikler yeni bağlantıda yeniden kurulmalı:\n // imza socket_id'ye bağlı, eskisi geçersiz.\n this.joined.forEach((c) => this.pending.add(c));\n this.joined.clear();\n this.onState(false);\n\n if (this.closed) return;\n\n const delay = BACKOFF[Math.min(this.attempt, BACKOFF.length - 1)];\n this.attempt++;\n\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => this.connect(), delay);\n }\n}\n","/**\n * Sohbet oturumu — çatısız durum yönetimi.\n *\n * `SignalbirdApp` ham uçları verir; burası bir sohbet ekranının gerçekten\n * ihtiyaç duyduğu şeyi verir: mesaj listesi, okunmamış sayısı, yazıyor durumu,\n * iyimser gönderim ve yoklama merdiveni. React/Vue/Angular/React Native\n * uyarlamaları bu sınıfa abone olur — üçünde de aynı mantığı yeniden yazmak,\n * üç ayrı hata takımı üretmek demekti.\n *\n * ── CANLI BAĞLANTI + YOKLAMA ──────────────────────────────────────────────\n *\n * 29 Ağu 2026'ya kadar burada yalnız yoklama vardı ve mobil, widget canlıya\n * geçtikten sonra da saniyede istek atmaya devam etti. Artık aynı soket\n * istemcisi (`../shared/socket`) burada da çalışıyor.\n *\n * YAYIN HABER TAŞIR, VERİ TAŞIMAZ: soketten gelen olay yalnız \"yeni bir şey\n * var\" der; mesajın kendisi HER ZAMAN kendi yetkimizle yeniden çekilir. Aksi\n * hâlde yayın kanalına düşen bir hata, okuma yetkisi olmayan birine mesaj\n * gövdesi göstermeye dönüşürdü.\n *\n * YOKLAMA KALDIRILMAZ, YAVAŞLAR. Bağlantı kurulduğunda panel açıkken 3 s\n * yerine 45 s, kapalıyken merdivenin son basamağı kullanılır: soket düşerse\n * ya da bir olay kaybolursa konuşma yine ilerler. Emniyet ağını sırf gereksiz\n * göründüğü için sökmek, düştüğünüz gün onu aramak demektir.\n *\n * Yoklama merdiveni (penyu deseni): panel açıkken 3 s, kapalıyken 20 s ×3 →\n * 60 s ×2 → 180 s. Yeni veri merdiveni sıfırlar; uygulama arka plandayken tur\n * atlanır.\n */\nimport { clientId, SignalbirdApp } from './client';\nimport { Socket } from '../shared/socket';\nimport type { BootstrapResult, Conversation, Message, SbResult, SessionInput, StartConversationInput, TopicOption, BootstrapChannel } from './types';\n\nexport interface ChatState {\n /** Sohbet bu uygulamada açık mı (`bootstrap` cevabı). */\n enabled: boolean;\n loading: boolean;\n conversation: Conversation | null;\n messages: Message[];\n unread: number;\n agentTyping: boolean;\n withinHours: boolean;\n /**\n * Ziyaretçinin seçebileceği destek konuları (boşsa konu adımı çizilmez).\n * Seçimi `setTopic()` taşır; ilk konuşma açılırken gönderilir.\n */\n topics: TopicOption[];\n /** Seçili konu (slug) — ilk konuşmayla birlikte gider. */\n topic: string | null;\n /** Son hatanın kodu — arayüz isterse gösterir, göstermezse yutar. */\n errorCode?: string;\n /**\n * Uygulamanın sohbet ayarları (renk, logo, tema, puanlama bağlantısı…).\n *\n * Ekran bunları PANELDEN alır, kendi içine gömmez: müşteri rengini ya da\n * puanlama adresini değiştirdiğinde yeni sürüm yayınlamak gerekmesin.\n */\n settings: BootstrapChannel['chat'] | null;\n}\n\nexport type ChatListener = (state: ChatState) => void;\n\nexport interface ChatSessionOptions {\n /** Panel açık mı — yoklama hızını belirler. */\n active?: boolean;\n /** Arka plandayken tur atlanır; varsayılan: `document.visibilityState`. */\n isVisible?: () => boolean;\n /** Açılışta oturum kurulurken kullanılacak ziyaretçi bilgisi. */\n visitor?: SessionInput;\n}\n\n/** Kapalı panelde yoklama aralıkları (ms) — son değer sonsuza kadar tekrarlar. */\nconst IDLE_LADDER = [20_000, 20_000, 20_000, 60_000, 60_000, 180_000];\nconst ACTIVE_INTERVAL = 3_000;\n\n/** Soket bağlıyken açık paneldeki yoklama — emniyet ağı, ana kanal değil. */\nconst ACTIVE_LIVE_INTERVAL = 45_000;\n\nexport class ChatSession {\n private state: ChatState = {\n enabled: false,\n loading: true,\n topics: [],\n topic: null,\n conversation: null,\n messages: [],\n unread: 0,\n agentTyping: false,\n withinHours: true,\n settings: null,\n };\n\n private listeners = new Set<ChatListener>();\n private timer: ReturnType<typeof setTimeout> | null = null;\n private step = 0;\n private active: boolean;\n private stopped = false;\n private polling = false;\n private socket: Socket | null = null;\n private live = false;\n /**\n * Bir sonraki `refresh()` İMLEÇSİZ olsun mu.\n *\n * \"Var olan mesaj değişti\" haberi geldiğinde açılır: imleçli çekim\n * (`?after=<son mesaj>`) o mesajı bir daha getirmez, dolayısıyla çeviri ya\n * da düzenleme ekrana hiç yansımaz.\n */\n private forceFull = false;\n\n constructor(\n private readonly app: SignalbirdApp,\n private readonly options: ChatSessionOptions = {}\n ) {\n this.active = options.active ?? false;\n }\n\n // ── Abonelik ──────────────────────────────────────────────────────────\n\n subscribe(listener: ChatListener): () => void {\n this.listeners.add(listener);\n listener(this.state);\n\n return () => this.listeners.delete(listener);\n }\n\n snapshot(): ChatState {\n return this.state;\n }\n\n // ── Yaşam döngüsü ─────────────────────────────────────────────────────\n\n /** Bootstrap + varsa mevcut konuşmayı yükler, sonra yoklamayı başlatır. */\n async start(): Promise<void> {\n this.stopped = false;\n\n const boot = await this.app.bootstrap();\n // Sunucu 1 Eyl'den beri `channel` gönderir; `app` eski sunucu uyumu.\n const app = boot.data?.channel ?? boot.data?.app;\n\n if (!boot.ok || !app?.chat_enabled) {\n this.patch({ enabled: false, loading: false, errorCode: boot.code });\n\n return;\n }\n\n this.patch({\n enabled: true,\n withinHours: app.within_hours ?? true,\n topics: boot.data?.topics ?? [],\n settings: app.chat ?? null,\n });\n\n this.openSocket(boot.data?.realtime);\n\n // Ziyaretçi yoksa oturum AÇILMAZ: ilk mesaja kadar bekleriz. Her sayfa\n // görüntülemesinde ziyaretçi kaydı açmak, hiç konuşmayacak binlerce boş\n // kayıt üretirdi.\n if (await this.app.currentVisitor()) {\n await this.refresh();\n }\n\n this.patch({ loading: false });\n this.schedule();\n }\n\n /** Panel açıldı/kapandı — yoklama hızı buna göre değişir. */\n setActive(active: boolean): void {\n if (this.active === active) return;\n\n this.active = active;\n this.step = 0;\n\n if (active) {\n // Kapanmış sohbet geri açılmaz: ekran yeniden görünür olduğunda\n // sıfırdan başlar (bkz. `refresh` ve widget'taki aynı kural).\n if (this.state.conversation?.status === 'closed') this.reset();\n\n void this.refresh();\n }\n\n this.schedule();\n }\n\n /**\n * Konuşmayı bırakır; sonraki mesaj YENİ bir konuşma açar.\n *\n * Ekranın \"yeni sohbet\" düğmesi de bunu çağırır. Sunucuda hiçbir şey\n * silinmez — yalnız bu oturumun neye baktığı değişir.\n */\n reset(): void {\n this.patch({ conversation: null, messages: [], unread: 0, agentTyping: false, errorCode: undefined });\n this.step = 0;\n }\n\n stop(): void {\n this.stopped = true;\n\n if (this.timer) clearTimeout(this.timer);\n\n this.timer = null;\n\n this.socket?.close();\n this.socket = null;\n this.live = false;\n }\n\n /** Canlı bağlantı kurulu mu — arayüz isterse gösterir (zorunlu değil). */\n get isLive(): boolean {\n return this.live;\n }\n\n // ── Eylemler ──────────────────────────────────────────────────────────\n\n /** Ön-form gönderildiğinde ya da uygulama kullanıcıyı tanıdığında. */\n async openSession(input: SessionInput): Promise<SbResult<unknown>> {\n const result = await this.app.startSession(input);\n\n if (result.ok) {\n // Kanal adı ziyaretçi kimliğini içerir; kimlik ancak ŞİMDİ doğdu.\n void this.joinVisitorChannel();\n await this.refresh();\n }\n\n return result;\n }\n\n /**\n * Mesaj gönderir. Konuşma yoksa açar.\n *\n * İyimser: mesaj listeye ANINDA düşer, `client_id` ile eşlenir. Sunucu\n * cevabı gelince yerel kopya onunla değiştirilir; başarısızsa `failed`\n * işaretlenir ve arayüz \"yeniden dene\" gösterebilir.\n */\n async send(body: string, attachments?: unknown[]): Promise<SbResult<unknown>> {\n const trimmed = body.trim();\n\n if (!trimmed && !attachments?.length) {\n return { ok: false, status: 0, code: 'EMPTY_BODY', message: 'Mesaj boş.' };\n }\n\n const cid = clientId();\n const optimistic: Message & { failed?: boolean } = {\n id: cid,\n client_id: cid,\n sender_type: 'visitor',\n body: trimmed,\n created_at: new Date().toISOString(),\n };\n\n this.patch({ messages: [...this.state.messages, optimistic] });\n\n // Ziyaretçi yoksa önce oturum: ilk mesaj kimliği de yaratır.\n if (!(await this.app.currentVisitor())) {\n const session = await this.app.startSession(this.options.visitor ?? {});\n\n if (!session.ok) return this.markFailed(cid, session);\n\n void this.joinVisitorChannel();\n }\n\n const conversation = this.state.conversation;\n\n const result = conversation\n ? await this.app.sendMessage(conversation.id, { body: trimmed, client_id: cid, attachments })\n : await this.app.startConversation({\n body: trimmed,\n client_id: cid,\n attachments,\n ...(this.state.topic ? { topic: this.state.topic } : {}),\n } as StartConversationInput);\n\n if (!result.ok) return this.markFailed(cid, result);\n\n await this.refresh();\n this.step = 0;\n this.schedule();\n\n return result;\n }\n\n /**\n * Ziyaretçinin konu seçimi. Konuşma AÇILDIKTAN sonra çağrılırsa etkisizdir:\n * açılmış konuşmanın konusunu ajan panelden değiştirir — ziyaretçiye kendi\n * konuşmasını yeniden sınıflandırma yetkisi vermek, atamayı da bozardı.\n */\n setTopic(slug: string | null): void {\n this.patch({ topic: slug });\n }\n\n /** İlk tuşta `true`, 2.5 s hareketsizlikte `false` — çağıran zamanlar. */\n typing(isTyping: boolean): void {\n const conversation = this.state.conversation;\n\n if (!conversation) return;\n\n void this.app.setTyping(conversation.id, isTyping);\n }\n\n /** Görülen son mesaja kadar okundu işaretler. */\n async markRead(): Promise<void> {\n const conversation = this.state.conversation;\n const last = this.state.messages[this.state.messages.length - 1];\n\n if (!conversation || !last) return;\n\n await this.app.markRead(conversation.id, last.id);\n this.patch({ unread: 0 });\n }\n\n async close(rating?: number, comment?: string): Promise<void> {\n const conversation = this.state.conversation;\n\n if (!conversation) return;\n\n if (typeof rating === 'number') {\n await this.app.rateConversation(conversation.id, rating, comment);\n }\n\n await this.app.closeConversation(conversation.id);\n await this.refresh();\n }\n\n /** Sunucudaki durumu çeker; imleç varsa yalnız yenileri ister. */\n async refresh(): Promise<void> {\n const current = this.state.conversation;\n\n if (!current) {\n const list = await this.app.listConversations();\n\n /*\n * YALNIZ AÇIK KONUŞMA BENİMSENİR (29 Ağu 2026).\n *\n * Eskiden listenin ilk kaydı alınıyordu ve o kayıt kapanmış olabilirdi:\n * ziyaretçi sohbeti bitirip ekranı yeniden açtığında, okunabilen ama\n * yazılamayan eski yazışma geri geliyordu. `closed` sunucuda da\n * ziyaretçi için finaldir; açık konuşma yoksa doğru cevap \"konuşma\n * yok\"tur ve ekran sıfırdan başlar.\n *\n * `resolved` bunun DIŞINDA: onu ajan işaretler, ziyaretçi hâlâ yazar.\n */\n const first = (list.data?.data ?? []).find((c) => c.status !== 'closed');\n\n if (!first) {\n this.patch({ errorCode: list.ok ? undefined : list.code });\n\n return;\n }\n\n const detail = await this.app.getConversation(first.id);\n\n this.applyConversation(detail.data?.conversation ?? first, true);\n\n return;\n }\n\n // `forceFull` açıksa imleç atlanır: değişen mesaj zaten imlecin\n // gerisinde kaldığı için `after` ile hiç dönmez.\n const after = this.forceFull ? undefined : this.lastServerMessageId();\n\n this.forceFull = false;\n\n const detail = await this.app.getConversation(current.id, after ? { after } : undefined);\n\n if (!detail.ok || !detail.data?.conversation) {\n this.patch({ errorCode: detail.code });\n\n return;\n }\n\n this.applyConversation(detail.data.conversation, !after);\n }\n\n // ── İç işler ──────────────────────────────────────────────────────────\n\n private applyConversation(conversation: Conversation, replace: boolean): void {\n const incoming = conversation.messages ?? [];\n const merged = replace ? incoming : mergeMessages(this.state.messages, incoming);\n\n // Yeni veri geldiyse merdiven sıfırlanır: konuşma canlandığında bir sonraki\n // yoklamayı üç dakika beklemek, kullanıcıyı terk edilmiş hissettirir.\n if (incoming.length) this.step = 0;\n\n this.patch({\n conversation,\n messages: merged,\n unread: conversation.unread_count ?? 0,\n agentTyping: !!conversation.agent_typing,\n withinHours: conversation.within_hours ?? this.state.withinHours,\n errorCode: undefined,\n });\n }\n\n /** İyimser kayıtlar sunucu kimliği taşımaz; imleç yalnız gerçek kimliktir. */\n private lastServerMessageId(): string | undefined {\n for (let i = this.state.messages.length - 1; i >= 0; i--) {\n const message = this.state.messages[i];\n\n if (message.id && !message.id.startsWith('c_') && message.id !== message.client_id) {\n return message.id;\n }\n }\n\n return undefined;\n }\n\n private markFailed(cid: string, result: SbResult<unknown>): SbResult<unknown> {\n this.patch({\n messages: this.state.messages.map((m) =>\n m.client_id === cid ? { ...m, failed: true } : m\n ) as Message[],\n errorCode: result.code,\n });\n\n return result;\n }\n\n // ── Canlı bağlantı ────────────────────────────────────────────────────\n\n /**\n * Ziyaretçinin kendi kanalına bağlanır (`visitor.<id>`).\n *\n * Kanal ziyaretçi kimliği kurulduktan SONRA bilinir; ilk mesajla kimlik\n * doğduğunda `refresh()` üzerinden yeniden denenir. Bağlantı kurulamazsa\n * hiçbir şey olmaz: yoklama zaten çalışıyor.\n */\n private openSocket(realtime?: { enabled: boolean; url?: string }): void {\n if (!realtime?.enabled || !realtime.url || this.socket) return;\n\n this.socket = new Socket(\n realtime,\n async (socketId, channel) => {\n const result = await this.app.socketAuth(socketId, channel);\n\n return result.ok && result.data ? result.data : null;\n },\n (event) => {\n // OLAYIN İÇİNDEKİ VERİ KULLANILMAZ, yalnız \"bir şey oldu\" bilgisi:\n // mesajı kendi yetkimizle çekeriz. Tek istisna `updated` işareti —\n // o, verinin kendisi değil, NASIL çekileceğinin talimatıdır.\n if (event.data.updated === true) this.forceFull = true;\n\n this.step = 0;\n void this.refresh();\n },\n (connected) => {\n this.live = connected;\n this.schedule();\n },\n );\n\n this.socket.connect();\n void this.joinVisitorChannel();\n }\n\n /** Ziyaretçi kimliği varsa kendi kanalına katılır; yoksa sessizce döner. */\n private async joinVisitorChannel(): Promise<void> {\n const visitor = await this.app.currentVisitor();\n\n if (visitor?.id) this.socket?.subscribe(`visitor.${visitor.id}`);\n }\n\n private schedule(): void {\n if (this.timer) clearTimeout(this.timer);\n if (this.stopped) return;\n\n /*\n * Soket bağlıysa yoklama YAVAŞLAR, DURMAZ. Açık panelde 3 s yerine 45 s;\n * kapalı panelde merdivenin son basamağı — bir olay kaybolsa bile\n * konuşma en geç bu kadar gecikir.\n */\n const delay = this.active\n ? (this.live ? ACTIVE_LIVE_INTERVAL : ACTIVE_INTERVAL)\n : this.live\n ? IDLE_LADDER[IDLE_LADDER.length - 1]\n : IDLE_LADDER[Math.min(this.step, IDLE_LADDER.length - 1)];\n\n this.timer = setTimeout(() => void this.tick(), delay);\n }\n\n private async tick(): Promise<void> {\n if (this.stopped || this.polling) return;\n\n // Arka plandaki sekme/uygulama tur atlar: görünmeyen sohbet için ağ\n // trafiği üretmek pil ve kota harcar.\n if (!this.visible()) {\n this.schedule();\n\n return;\n }\n\n this.polling = true;\n\n try {\n await this.refresh();\n } finally {\n this.polling = false;\n }\n\n if (!this.active) this.step++;\n\n this.schedule();\n }\n\n private visible(): boolean {\n if (this.options.isVisible) return this.options.isVisible();\n\n try {\n if (typeof document !== 'undefined' && document.visibilityState) {\n return document.visibilityState === 'visible';\n }\n } catch {\n /* yok say */\n }\n\n return true;\n }\n\n private patch(partial: Partial<ChatState>): void {\n this.state = { ...this.state, ...partial };\n\n for (const listener of this.listeners) {\n try {\n listener(this.state);\n } catch (error) {\n // Bir dinleyicinin hatası diğerlerini ve oturumu düşürmemeli.\n console.warn('[signalbird] dinleyici hatası:', error);\n }\n }\n }\n}\n\n/** Sunucu kaydı, aynı `client_id`'li yerel kopyanın yerine geçer. */\nfunction mergeMessages(existing: Message[], incoming: Message[]): Message[] {\n if (!incoming.length) return existing;\n\n const byKey = new Map<string, Message>();\n\n for (const message of existing) {\n byKey.set(message.client_id ?? message.id, message);\n }\n\n for (const message of incoming) {\n const key = message.client_id ?? message.id;\n byKey.delete(key);\n byKey.set(key, message);\n }\n\n return [...byKey.values()].sort((a, b) => (a.created_at ?? '').localeCompare(b.created_at ?? ''));\n}\n","/**\n * `signalbird/angular` — Angular servisi ve sağlayıcısı.\n *\n * Dekoratör KULLANMAZ: `@Injectable()` yazsaydık paketin derlenmesi Angular\n * sürümüne bağlanırdı ve her büyük sürümde yeniden yayın gerekirdi. Bunun\n * yerine düz sınıf + `provideSignalbird()` fabrikası veriyoruz; Angular'ın DI'ı\n * bunu sorunsuz kabul eder ve sürümden bağımsızdır.\n *\n * RxJS bir `peerDependency`'dir (Angular zaten getirir).\n */\nimport { BehaviorSubject, type Observable } from 'rxjs';\nimport { ChatSession, SignalbirdApp } from '../app';\nimport type { AppConfig, ChatState, IdentifyInput, RegisterDeviceInput, SessionInput } from '../app';\n\n/** DI belirteci — Angular'ın `InjectionToken`'ına sarılır (aşağıda). */\nexport const SIGNALBIRD_CONFIG = 'SIGNALBIRD_CONFIG';\n\n/**\n * Uygulama başına tek örnek (`providedIn: 'root'` karşılığı).\n *\n * Sohbet durumu bir `Observable`'dır; şablon `| async` ile doğrudan bağlanır.\n */\nexport class SignalbirdService {\n readonly client: SignalbirdApp;\n\n private readonly session: ChatSession;\n private readonly subject: BehaviorSubject<ChatState>;\n private started = false;\n\n constructor(config: AppConfig) {\n this.client = new SignalbirdApp(config);\n this.session = new ChatSession(this.client, { active: false });\n this.subject = new BehaviorSubject<ChatState>(this.session.snapshot());\n\n this.session.subscribe((state) => this.subject.next(state));\n }\n\n /** Sohbet durumu akışı. İlk abone olduğunda oturum başlar. */\n chat$(): Observable<ChatState> {\n if (!this.started) {\n this.started = true;\n void this.session.start();\n }\n\n return this.subject.asObservable();\n }\n\n /** Panel açık mı — yoklama hızını belirler. */\n setOpen(open: boolean): void {\n this.session.setActive(open);\n }\n\n send(body: string, attachments?: unknown[]): Promise<unknown> {\n return this.session.send(body, attachments);\n }\n\n typing(isTyping: boolean): void {\n this.session.typing(isTyping);\n }\n\n markRead(): Promise<void> {\n return this.session.markRead();\n }\n\n closeConversation(rating?: number, comment?: string): Promise<void> {\n return this.session.close(rating, comment);\n }\n\n openSession(input: SessionInput): Promise<unknown> {\n return this.session.openSession(input);\n }\n\n /**\n * Konuşmayı bırakır; sonraki mesaj YENİ bir konuşma açar (29 Ağu 2026).\n * Kapanmış sohbet geri açılmadığı için arayüzün \"yeni sohbet\" düğmesine\n * bağlanacak bir eyleme ihtiyacı var.\n */\n resetConversation(): void {\n this.session.reset();\n }\n\n identify(input: IdentifyInput): Promise<unknown> {\n return this.client.identify(input);\n }\n\n registerDevice(input: RegisterDeviceInput): Promise<unknown> {\n return this.client.registerDevice(input);\n }\n\n /** Uygulama kapanırken ya da testte: yoklamayı durdurur. */\n destroy(): void {\n this.session.stop();\n this.subject.complete();\n }\n}\n\n/**\n * `bootstrapApplication(App, { providers: [provideSignalbird({ publicKey })] })`\n *\n * Dönen nesne Angular'ın `Provider` biçimindedir ama tipi buraya gömülmez —\n * paket Angular'a derleme zamanı bağımlılık taşımaz.\n */\nexport function provideSignalbird(config: AppConfig): {\n provide: typeof SignalbirdService;\n useFactory: () => SignalbirdService;\n} {\n return {\n provide: SignalbirdService,\n useFactory: () => new SignalbirdService(config),\n };\n}\n"]}
package/dist/angular.mjs CHANGED
@@ -512,7 +512,7 @@ var ChatSession = class {
512
512
  async start() {
513
513
  this.stopped = false;
514
514
  const boot = await this.app.bootstrap();
515
- const app = boot.data?.app;
515
+ const app = boot.data?.channel ?? boot.data?.app;
516
516
  if (!boot.ok || !app?.chat_enabled) {
517
517
  this.patch({ enabled: false, loading: false, errorCode: boot.code });
518
518
  return;